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.commons.logging.*;
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 private Log log = LogFactory.getLog(LDAPUserGroup.class);
48 private Log resourceAdminLog = LogFactory.getLog(GUMS.resourceAdminLog);
49 private UserGroupDB db;
50 private String persistenceFactory = "";
51 private Configuration conf;
52 private String server = "";
53 private String query = "";
54 private String certDNField = "description";
55 protected ConfigurationStore confStore;
56
57
58
59
60 public LDAPUserGroup() {
61 super();
62 }
63
64
65
66
67 public LDAPUserGroup(Configuration configuration) {
68 super(configuration);
69 }
70
71
72
73
74 public LDAPUserGroup(Configuration configuration, String name) {
75 super(configuration, name);
76 }
77
78 public UserGroup clone(Configuration configuration) {
79 LDAPUserGroup userGroup = new LDAPUserGroup(configuration, new String(getName()));
80 userGroup.setDescription(new String(getDescription()));
81 userGroup.setPersistenceFactory(new String(persistenceFactory));
82 userGroup.setAccess(new String(getAccess()));
83 userGroup.setQuery(new String(getQuery()));
84 userGroup.setServer(new String(getServer()));
85 userGroup.setCertDNField(new String(certDNField));
86 return userGroup;
87 }
88
89 public boolean equals(Object obj) {
90 if (obj instanceof LDAPUserGroup) {
91 LDAPUserGroup group = (LDAPUserGroup) obj;
92 if ((server == null ? group.server == null : server.equals(group.server)) &&
93 (query == null ? group.query == null : query.equals(group.query)) &&
94 (getName() == null ? group.getName() == null : getName().equals(group.getName())) &&
95 (persistenceFactory == null ? group.persistenceFactory == null : persistenceFactory.equals(group.persistenceFactory))) {
96 return true;
97 }
98 }
99 return false;
100 }
101
102
103
104
105
106
107 public String getCertDNField() {
108 return certDNField;
109 }
110
111 public java.util.List getMemberList() {
112 return getDB().retrieveMembers();
113 }
114
115
116
117
118
119
120 public String getPersistenceFactory() {
121 return persistenceFactory;
122 }
123
124
125
126
127
128
129 public String getQuery() {
130 return this.query;
131 }
132
133
134
135
136
137
138 public String getServer() {
139 return this.server;
140 }
141
142 public String getType() {
143 return "ldap";
144 }
145
146 public int hashCode() {
147 return query.hashCode();
148 }
149
150 public boolean isInGroup(GridUser user) {
151 return getDB().isMemberInGroup(user);
152 }
153
154 public Map retrievePeopleMap(DirContext ldap) throws javax.naming.NamingException {
155 NamingEnumeration people = ldap.search("ou=People", "("+certDNField+"=*)", null);
156 Map map = new Hashtable();
157 while (people.hasMore()) {
158 SearchResult person = (SearchResult) people.next();
159 Attributes personAtts = person.getAttributes();
160 String ldapDN = person.getName();
161 if (person.isRelative()) {
162 ldapDN = ldapDN + ",ou=People," + ldap.getNameInNamespace();
163 }
164
165 String certDN = (String) personAtts.get(certDNField).get();
166 if (certDN.startsWith("subject=")) {
167 certDN = certDN.substring(8);
168 }
169 certDN = certDN.trim();
170 map.put(ldapDN, certDN);
171 }
172 return map;
173 }
174
175
176
177
178
179
180 public void setCertDNField(String certDNField) {
181 this.certDNField = certDNField;
182 }
183
184
185
186
187
188
189 public void setPersistenceFactory(String persistenceFactory) {
190 this.persistenceFactory = persistenceFactory;
191 }
192
193
194
195
196
197
198 public void setQuery(String query) {
199 this.query = query;
200 }
201
202
203
204
205
206 public void setServer(String server) {
207 this.server = server;
208 }
209
210 public String toString() {
211 return "LDAPGroup: ldap://"+server+"/"+query;
212 }
213
214 public String toString(String bgColor) {
215 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>";
216 }
217
218 public String toXML() {
219 return "\t\t<ldapUserGroup\n"+
220 "\t\t\tname='"+getName()+"'\n"+
221 "\t\t\taccess='"+accessTypes[accessIndex]+"'\n" +
222 "\t\t\tdescription='"+getDescription()+"'\n"+
223 "\t\t\tserver='"+server+"'\n" +
224 "\t\t\tquery='"+query+"'\n" +
225 "\t\t\tcertDNField='"+certDNField+"'\n" +
226 "\t\t\tpersistenceFactory='"+persistenceFactory+"'/>\n\n";
227 }
228
229 public void updateMembers() {
230 getDB().loadUpdatedList(retrieveMembers());
231 }
232
233 private UserGroupDB getDB() {
234 if (db==null)
235 db = getConfiguration().getPersistenceFactory(persistenceFactory).retrieveUserGroupDB( getName() );
236 return db;
237 }
238
239 private List retrieveGroupMembers(DirContext rootCtx, Attribute members) throws javax.naming.NamingException {
240 Map people = retrievePeopleMap(rootCtx);
241 NamingEnumeration names = members.getAll();
242 List list = new ArrayList();
243 while (names.hasMore()) {
244
245 String ldapName = (String) names.next();
246 ldapName = ldapName.trim();
247 String certDN = (String) people.get(ldapName);
248 if (certDN == null) {
249 resourceAdminLog.warn("Member of a LDAP VO group not mapped to any certificate: '" + ldapName + "'");
250 } else {
251 list.add(new GridUser(certDN, null));
252 }
253 }
254 if (list.isEmpty()) {
255 resourceAdminLog.warn("The following group returned no members: " + this);
256 }
257 return list;
258 }
259
260
261
262
263
264
265
266 private synchronized List retrieveMembers() {
267 java.util.Properties properties = retrieveProperties();
268 log.info("Retrieving members from '" + properties.getProperty("java.naming.provider.url") + "' '" + query + "'");
269 try {
270 javax.naming.directory.DirContext jndiCtx = new javax.naming.directory.InitialDirContext(properties);
271 if (query.startsWith("ou=People,")) {
272 String voRoot = query.substring(query.indexOf(',')+1);
273 DirContext rootCtx = (DirContext) jndiCtx.lookup(voRoot);
274 return retrieveVOMembers(rootCtx);
275 } else if (query.startsWith("ou=")) {
276 Attributes atts = jndiCtx.getAttributes(query);
277 Attribute members = atts.get("member");
278 if (members == null) {
279 throw new RuntimeException("Couldn't retrieve the list of members from the LDAP group: missing attribute member");
280 }
281 String voRoot = query.substring(query.indexOf(',')+1);
282 DirContext rootCtx = (DirContext) jndiCtx.lookup(voRoot);
283 return retrieveGroupMembers(rootCtx, members);
284 } else if (query.startsWith("o=")) {
285 DirContext rootCtx = (DirContext) jndiCtx.lookup(query);
286 return retrieveVOMembers(rootCtx);
287 } else {
288 throw new IllegalArgumentException("The query is not understood by the LDAP group. It is expected to start with \"ou=...\" or \"o=...\"");
289 }
290
291 } catch (javax.naming.NamingException e) {
292 String message = "Couldn't retrieve users from LDAP server: " + e;
293
294
295
296 log.error("Couldn't retrieve LDAP users: ", e);
297 throw new RuntimeException(message, e);
298 }
299 }
300
301 private Properties retrieveProperties() {
302 Properties properties = new java.util.Properties();
303 properties.put(Context.PROVIDER_URL, "ldap://"+server);
304 properties.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");
305 properties.put(Context.SECURITY_PROTOCOL, "none");
306 return properties;
307 }
308
309 private List retrieveVOMembers(DirContext rootCtx) throws NamingException {
310 Map people = retrievePeopleMap(rootCtx);
311 List list = new ArrayList(people.values());
312 if (list.isEmpty()) {
313 resourceAdminLog.warn("The following group returned no members: " + this);
314 }
315 Iterator iter = list.iterator();
316 List users = new ArrayList();
317 while (iter.hasNext()) {
318 String dn = (String) iter.next();
319 users.add(new GridUser(dn, null));
320 }
321 if (list.isEmpty()) {
322 resourceAdminLog.warn("The following group returned no members: " + this);
323 }
324 return users;
325 }
326 }