View Javadoc

1   /*
2   * Licensed to the Apache Software Foundation (ASF) under one or more
3   * contributor license agreements.  See the NOTICE file distributed with
4   * this work for additional information regarding copyright ownership.
5   * The ASF licenses this file to You under the Apache License, Version 2.0
6   * (the "License"); you may not use this file except in compliance with
7   * the License.  You may obtain a copy of the License at
8   *
9   *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17  package org.apache.jetspeed.security.spi.impl.ldap;
18  
19  import java.security.Principal;
20  import java.util.ArrayList;
21  import java.util.Enumeration;
22  import java.util.Iterator;
23  import java.util.List;
24  
25  import javax.naming.NamingEnumeration;
26  import javax.naming.NamingException;
27  import javax.naming.directory.Attribute;
28  import javax.naming.directory.Attributes;
29  import javax.naming.directory.BasicAttribute;
30  import javax.naming.directory.BasicAttributes;
31  import javax.naming.directory.DirContext;
32  import javax.naming.directory.SearchControls;
33  import javax.naming.directory.SearchResult;
34  
35  import org.apache.commons.lang.StringUtils;
36  import org.apache.commons.logging.Log;
37  import org.apache.commons.logging.LogFactory;
38  import org.apache.jetspeed.security.SecurityException;
39  import org.apache.jetspeed.security.impl.UserPrincipalImpl;
40  
41  
42  public class LdapMemberShipDaoImpl extends LdapPrincipalDaoImpl implements LdapMembershipDao {
43  
44  	/*** The logger. */
45  	private static final Log logger = LogFactory.getLog(LdapMemberShipDaoImpl.class);
46  
47  	public LdapMemberShipDaoImpl() throws SecurityException {
48  		super();
49  	}
50  	
51  	public LdapMemberShipDaoImpl(LdapBindingConfig config) throws SecurityException {
52  		super(config);
53  	}	
54  
55  	/* (non-Javadoc)
56  	 * @see org.apache.jetspeed.security.spi.impl.ldap.LdapMembershipDao#searchGroupMemberShipByGroup(java.lang.String, javax.naming.directory.SearchControls)
57  	 */
58  	public String[] searchGroupMemberShipByGroup(final String userPrincipalUid, SearchControls cons) throws NamingException {
59  		
60  		String query = "(&(" + getGroupMembershipAttribute() + "=" + getUserDN(userPrincipalUid) + ")" + getGroupFilter()  + ")";
61  		
62  	    if (logger.isDebugEnabled())
63  	    {
64  	        logger.debug("query[" + query + "]");
65  	    }
66  	    
67  	    cons.setSearchScope(getSearchScope());
68          String groupFilterBase = getGroupFilterBase();
69  	    NamingEnumeration searchResults = ((DirContext) ctx).search(groupFilterBase,query , cons);	    
70  
71  	   List groupPrincipalUids = new ArrayList();
72  	    while (searchResults.hasMore())
73  	    {
74  	        SearchResult result = (SearchResult) searchResults.next();
75  	        Attributes answer = result.getAttributes();
76  	        groupPrincipalUids.addAll(getAttributes(getAttribute(getGroupIdAttribute(), answer)));
77  	    }
78  	    return (String[]) groupPrincipalUids.toArray(new String[groupPrincipalUids.size()]);
79  	
80  	}
81  
82  	/* (non-Javadoc)
83  	 * @see org.apache.jetspeed.security.spi.impl.ldap.LdapMembershipDao#searchGroupMemberShipByUser(java.lang.String, javax.naming.directory.SearchControls)
84  	 */
85  	public String[] searchGroupMemberShipByUser(final String userPrincipalUid, SearchControls cons) throws NamingException {
86  		NamingEnumeration searchResults = searchByWildcardedUid(userPrincipalUid, cons);
87  	    
88  	    if (!searchResults.hasMore())
89  	    {
90  	        throw new NamingException("Could not find any user with uid[" + userPrincipalUid + "]");
91  	    }
92  	    
93  		Attributes userAttributes = getFirstUser(searchResults);
94  		List groupUids = new ArrayList();
95  		Attribute attr = getAttribute(getUserGroupMembershipAttribute(), userAttributes);
96  		 List attrs = getAttributes(attr);
97  		        Iterator it = attrs.iterator();
98  		        while(it.hasNext()) {
99  		        	String cnfull = (String)it.next();
100 		        	if(cnfull.toLowerCase().indexOf(getRoleFilterBase().toLowerCase())!=-1) {
101 			        	String cn = extractLdapAttr(cnfull,getRoleUidAttribute());
102 			        	groupUids.add(cn);
103 		        	}
104 		        }
105 	    //List uids = getAttributes(getAttribute(getUserGroupMembershipAttribute(), userAttributes),getGroupFilterBase());
106 	    return (String[]) groupUids.toArray(new String[groupUids.size()]);
107 	}
108 
109 	/* (non-Javadoc)
110 	 * @see org.apache.jetspeed.security.spi.impl.ldap.LdapMembershipDao#searchRoleMemberShipByRole(java.lang.String, javax.naming.directory.SearchControls)
111 	 */
112 	public String[] searchRoleMemberShipByRole(final String userPrincipalUid, SearchControls cons) throws NamingException {
113 
114 		String query = "(&(" + getRoleMembershipAttribute() + "=" + getUserDN(userPrincipalUid) + ")" + getRoleFilter()  + ")";
115 		
116 	    if (logger.isDebugEnabled())
117 	    {
118 	        logger.debug("query[" + query + "]");
119 	    }
120 
121 	    cons.setSearchScope(getSearchScope());
122 	    NamingEnumeration searchResults = ((DirContext) ctx).search(getRoleFilterBase(),query , cons);
123 	    List rolePrincipalUids = new ArrayList();
124 	     while (searchResults.hasMore())
125 	     {
126 	    	 
127 	         SearchResult result = (SearchResult) searchResults.next();
128 	         Attributes answer = result.getAttributes();
129 	         rolePrincipalUids.addAll(getAttributes(getAttribute(getRoleIdAttribute(), answer)));
130 	     }
131 	     return (String[]) rolePrincipalUids.toArray(new String[rolePrincipalUids.size()]);
132 	}
133 
134 	/* (non-Javadoc)
135 	 * @see org.apache.jetspeed.security.spi.impl.ldap.LdapMembershipDao#searchRoleMemberShipByUser(java.lang.String, javax.naming.directory.SearchControls)
136 	 */
137 	public String[] searchRoleMemberShipByUser(final String userPrincipalUid, SearchControls cons) throws NamingException {
138 	
139 		NamingEnumeration results = searchByWildcardedUid(userPrincipalUid, cons);
140 	
141 		if (!results.hasMore())
142 		{
143 		    throw new NamingException("Could not find any user with uid[" + userPrincipalUid + "]");
144 		}
145 		
146 		Attributes userAttributes = getFirstUser(results);
147 		List newAttrs = new ArrayList();
148 		Attribute attr = getAttribute(getUserRoleMembershipAttribute(), userAttributes);
149 		 List attrs = getAttributes(attr);
150 		        Iterator it = attrs.iterator();
151 		        while(it.hasNext()) {
152 		        	String cnfull = (String)it.next();
153 		        	if(cnfull.toLowerCase().indexOf(getRoleFilterBase().toLowerCase())!=-1) {
154 			        	String cn = extractLdapAttr(cnfull,getRoleUidAttribute());
155 			        	newAttrs.add(cn);
156 		        	}
157 		        }
158 		return (String[]) newAttrs.toArray(new String[newAttrs.size()]);
159 	}
160 
161 	/* (non-Javadoc)
162 	 * @see org.apache.jetspeed.security.spi.impl.ldap.LdapMembershipDao#searchUsersFromGroupByGroup(java.lang.String, javax.naming.directory.SearchControls)
163 	 */
164 	public String[] searchUsersFromGroupByGroup(final String groupPrincipalUid, SearchControls cons)
165 	        throws NamingException
166 	{
167 	
168 		String query = "(&(" + getGroupIdAttribute() + "=" + (groupPrincipalUid) + ")" + getGroupFilter() + ")";
169 	    
170 		if (logger.isDebugEnabled())
171 	    {
172 	        logger.debug("query[" + query + "]");
173 	    }
174 	    
175 	    ArrayList userPrincipalUids=new ArrayList();
176 	    
177 	    cons.setSearchScope(getSearchScope());
178 	    NamingEnumeration results = ((DirContext) ctx).search(getGroupFilterBase(),query , cons);	    
179 		
180 	    while (results.hasMore())
181 	    {
182 	        SearchResult result = (SearchResult) results.next();
183 	        Attributes answer = result.getAttributes();
184 	        
185 	        List newAttrs = new ArrayList();
186 	        
187 	        Attribute userPrincipalUid = getAttribute(getGroupMembershipAttribute(), answer);
188 	        List attrs = getAttributes(userPrincipalUid);
189 	        Iterator it = attrs.iterator();
190 	        while(it.hasNext()) {
191 	        	String uidfull = (String)it.next();
192 	        	if (!StringUtils.isEmpty(uidfull)) {
193 		        	if (uidfull.toLowerCase().indexOf(getUserFilterBase().toLowerCase())!=-1) {
194 			        	String uid = extractLdapAttr(uidfull,getUserIdAttribute());
195 		        		newAttrs.add(uid);
196 		        	}
197 	        	}
198 	        }
199 	        userPrincipalUids.addAll(newAttrs);
200 	    }
201 	    return (String[]) userPrincipalUids.toArray(new String[userPrincipalUids.size()]);
202 	}
203 
204 	/* (non-Javadoc)
205 	 * @see org.apache.jetspeed.security.spi.impl.ldap.LdapMembershipDao#searchUsersFromGroupByUser(java.lang.String, javax.naming.directory.SearchControls)
206 	 */
207 	public String[] searchUsersFromGroupByUser(final String groupPrincipalUid, SearchControls cons)
208 	        throws NamingException
209 	{
210 		
211 		String query = "(&(" + getUserGroupMembershipAttribute() + "=" + getGroupDN(groupPrincipalUid) + ")" + getUserFilter() + ")";
212 	    if (logger.isDebugEnabled())
213 	    {
214 	        logger.debug("query[" + query + "]");
215 	    }
216 
217 	    cons.setSearchScope(getSearchScope());
218 	    NamingEnumeration results = ((DirContext) ctx).search(getUserFilterBase(),query , cons);	    
219 
220 	    ArrayList userPrincipalUids = new ArrayList();
221 	    
222 	    while (results.hasMore())
223 	    {
224 	        SearchResult result = (SearchResult) results.next();
225 	        Attributes answer = result.getAttributes();
226 	        userPrincipalUids.addAll(getAttributes(getAttribute(getUserIdAttribute(), answer)));
227 	    }
228 	    return (String[]) userPrincipalUids.toArray(new String[userPrincipalUids.size()]);
229 	}
230 	
231 	public String[] searchRolesFromGroupByGroup(final String groupPrincipalUid,
232 			SearchControls cons) throws NamingException {
233 
234 		String query = "(&(" + getGroupIdAttribute() + "=" + (groupPrincipalUid) + ")" + getGroupFilter() + ")";
235 
236 		if (logger.isDebugEnabled()) {
237 			logger.debug("query[" + query + "]");
238 		}
239 
240 		ArrayList rolePrincipalUids = new ArrayList();
241 
242 	    cons.setSearchScope(getSearchScope());
243 	    NamingEnumeration groups = ((DirContext) ctx).search(getGroupFilterBase(),query , cons);	    
244 
245 		while (groups.hasMore()) {
246 			SearchResult group = (SearchResult) groups.next();
247 			Attributes groupAttributes = group.getAttributes();
248 
249 			Attribute rolesFromGroup = getAttribute(getGroupMembershipForRoleAttribute(), groupAttributes);
250 			List roleDNs = getAttributes(rolesFromGroup,getRoleFilterBase());
251 			Iterator it = roleDNs.iterator();
252 			while (it.hasNext()) {
253 				String roleDN = (String) it.next();
254 				if (!StringUtils.isEmpty(roleDN)) {
255 					String roleId = extractLdapAttr(roleDN,getRoleUidAttribute());
256 					if (roleId!=null) {
257 						NamingEnumeration rolesResults = searchRoleByWildcardedUid(roleId, cons);
258 						if (rolesResults.hasMore())
259 							if(rolesResults.nextElement()!=null)
260 								rolePrincipalUids.add(roleId);
261 					}
262 				}
263 			}
264 		}
265 		return (String[]) rolePrincipalUids.toArray(new String[rolePrincipalUids.size()]);
266 	}
267 
268 	/*
269 	 * (non-Javadoc)
270 	 * 
271 	 * @see org.apache.jetspeed.security.spi.impl.ldap.LdapMembershipDao#searchUsersFromGroupByUser(java.lang.String,
272 	 *      javax.naming.directory.SearchControls)
273 	 */
274 	public String[] searchRolesFromGroupByRole(final String groupPrincipalUid,
275 			SearchControls cons) throws NamingException {
276 
277 		String query = "(&(" + getRoleGroupMembershipForRoleAttribute() + "=" + getGroupDN(groupPrincipalUid) + ")" + getRoleFilter() + ")";
278 		
279 		if (logger.isDebugEnabled()) {
280 			logger.debug("query[" + query + "]");
281 		}
282 		
283 	    cons.setSearchScope(getSearchScope());
284 	    NamingEnumeration results = ((DirContext) ctx).search(getRoleFilterBase(),query , cons);	    
285 
286 		ArrayList rolePrincipalUids = new ArrayList();
287 
288 		while (results.hasMore()) {
289 			SearchResult result = (SearchResult) results.next();
290 			Attributes answer = result.getAttributes();
291 			rolePrincipalUids.addAll(getAttributes(getAttribute(getRoleIdAttribute(), answer)));
292 		}
293 		return (String[]) rolePrincipalUids
294 				.toArray(new String[rolePrincipalUids.size()]);
295 	}
296 
297 
298 	/* (non-Javadoc)
299 	 * @see org.apache.jetspeed.security.spi.impl.ldap.LdapMembershipDao#searchUsersFromRoleByRole(java.lang.String, javax.naming.directory.SearchControls)
300 	 */
301 	public String[] searchUsersFromRoleByRole(final String rolePrincipalUid, SearchControls cons)
302 	        throws NamingException
303 	{
304 	
305 		String query = "(&(" + getRoleIdAttribute() + "=" + (rolePrincipalUid) + ")" + getRoleFilter() + ")";
306 	    
307 		if (logger.isDebugEnabled())
308 	    {
309 	        logger.debug("query[" + query + "]");
310 	    }
311 	    
312 	    ArrayList userPrincipalUids=new ArrayList();
313 
314 	    cons.setSearchScope(getSearchScope());
315 	    NamingEnumeration results = ((DirContext) ctx).search(getRoleFilterBase(),query , cons);	    
316 		
317 	    while (results.hasMore())
318 	    {
319 	        SearchResult result = (SearchResult) results.next();
320 	        Attributes answer = result.getAttributes();
321 	        
322 	        Attribute userPrincipalUid = getAttribute(getRoleMembershipAttribute(), answer);
323 	        List attrs = getAttributes(userPrincipalUid);
324 	        Iterator it = attrs.iterator();
325 	        while(it.hasNext()) {
326 	        	String uidfull = (String)it.next();
327 	        	if (!StringUtils.isEmpty(uidfull)) {	        	
328 		        	String uid = extractLdapAttr(uidfull,getUserIdAttribute());
329 		        	userPrincipalUids.add(uid);
330 	        	}
331 	        }
332 	    }
333 	    return (String[]) userPrincipalUids.toArray(new String[userPrincipalUids.size()]);
334 	}
335 
336 	/* (non-Javadoc)
337 	 * @see org.apache.jetspeed.security.spi.impl.ldap.LdapMembershipDao#searchUsersFromRoleByUser(java.lang.String, javax.naming.directory.SearchControls)
338 	 */
339 	public String[] searchUsersFromRoleByUser(final String rolePrincipalUid, SearchControls cons)
340 	throws NamingException
341 	{
342 	
343 		String query = "(&(" + getUserRoleMembershipAttribute() + "=" + getRoleDN(rolePrincipalUid) + ")" + getUserFilter() + ")";
344 		if (logger.isDebugEnabled())
345 		{
346 		    logger.debug("query[" + query + "]");
347 		}
348 	    
349 		cons.setSearchScope(getSearchScope());
350 	    NamingEnumeration results = ((DirContext) ctx).search(getUserFilterBase(),query , cons);	    
351 
352 		ArrayList userPrincipalUids = new ArrayList();
353 		
354 		while (results.hasMore())
355 		{
356 		    SearchResult result = (SearchResult) results.next();
357 		    Attributes answer = result.getAttributes();
358 		    userPrincipalUids.addAll(getAttributes(getAttribute(getUserIdAttribute(), answer)));
359 		}
360 		return (String[]) userPrincipalUids.toArray(new String[userPrincipalUids.size()]);
361 	}
362 
363     /***
364      * @param attr
365      * @return
366      * @throws NamingException
367      */
368     protected List getAttributes(Attribute attr) throws NamingException
369     {
370     	return getAttributes(attr, null);
371     }
372     /***
373      * @param attr
374      * @return
375      * @throws NamingException
376      */
377     protected List getAttributes(Attribute attr,String filter) throws NamingException
378     {
379         List uids = new ArrayList();
380         if (attr != null)
381         {
382             Enumeration groupUidEnum = attr.getAll();
383             while (groupUidEnum.hasMoreElements())
384             {
385             	String groupDN = (String)groupUidEnum.nextElement();
386             	if (filter==null) {
387             		uids.add(groupDN);
388             	} else if (filter!=null && groupDN.toLowerCase().indexOf(filter.toLowerCase())!=-1) {
389             		uids.add(groupDN);
390             	}
391             }
392         }
393         return uids;
394     }	
395 
396     /***
397      * @param results
398      * @return
399      * @throws NamingException
400      */
401     private Attributes getFirstUser(NamingEnumeration results) throws NamingException
402     {
403         SearchResult result = (SearchResult) results.next();
404         Attributes answer = result.getAttributes();
405 
406         return answer;
407     }
408     
409 
410 
411 	/***
412 	 * <p>
413 	 * A template method for defining the attributes for a particular LDAP class.
414 	 * </p>
415 	 * 
416 	 * @param principalUid The principal uid.
417 	 * @return the LDAP attributes object for the particular class.
418 	 */
419 	protected Attributes defineLdapAttributes(final String principalUid)
420 	{
421 	    Attributes attrs = new BasicAttributes(true);
422 	    BasicAttribute classes = new BasicAttribute("objectclass");
423 	
424 	    classes.add("top");
425 	    classes.add("person");
426 	    classes.add("organizationalPerson");
427 	    classes.add("inetorgperson");
428 	    attrs.put(classes);
429 	    attrs.put("cn", principalUid);
430 	    attrs.put("sn", principalUid);
431 	
432 	    return attrs;
433 	}
434 
435 	/***
436      * @see org.apache.jetspeed.security.spi.impl.ldap.LdapPrincipalDaoImpl#getDnSuffix()
437      */
438     protected String getDnSuffix()
439     {
440         return this.getUserFilterBase();
441     }
442 
443 	/***
444 	 * <p>
445 	 * Creates a GroupPrincipal object.
446 	 * </p>
447 	 * 
448 	 * @param principalUid The principal uid.
449 	 * @return A group principal object.
450 	 */
451 	protected Principal makePrincipal(String principalUid)
452 	{
453 	    return new UserPrincipalImpl(principalUid);
454 	}    
455 	
456 	private String extractLdapAttr(String dn,String ldapAttrName) {
457 
458 		String dnLowerCase = dn.toLowerCase();
459 		String ldapAttrNameLowerCase = ldapAttrName.toLowerCase();
460 		
461 		if (dnLowerCase.indexOf(ldapAttrNameLowerCase + "=")==-1)
462 			return null;
463 		
464 		if (dn.indexOf(",")!=-1 && dnLowerCase.indexOf(ldapAttrNameLowerCase + "=")!=-1)
465 			return dn.substring(dnLowerCase.indexOf(ldapAttrNameLowerCase)+ldapAttrName.length()+1,dn.indexOf(","));
466 		return dn.substring(dnLowerCase.indexOf(ldapAttrNameLowerCase)+ldapAttrName.length()+1,dn.length());
467 	}
468 
469 	protected String[] getObjectClasses() {
470 		return this.getUserObjectClasses();
471 	}
472 	
473 	protected String getUidAttributeForPrincipal() {
474 		return this.getUserUidAttribute();
475 	}
476 
477 	protected String[] getAttributes() {
478 		return getUserAttributes();
479 	}
480 
481 	protected String getEntryPrefix() {
482 		return "uid";
483 	}
484 
485 	protected String getSearchSuffix() {
486 		return this.getUserFilter();
487 	}	
488 }