001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.jetspeed.security.spi.impl.ldap;
018:
019: import java.security.Principal;
020: import java.util.ArrayList;
021: import java.util.Enumeration;
022: import java.util.Iterator;
023: import java.util.List;
024:
025: import javax.naming.NamingEnumeration;
026: import javax.naming.NamingException;
027: import javax.naming.directory.Attribute;
028: import javax.naming.directory.Attributes;
029: import javax.naming.directory.BasicAttribute;
030: import javax.naming.directory.BasicAttributes;
031: import javax.naming.directory.DirContext;
032: import javax.naming.directory.SearchControls;
033: import javax.naming.directory.SearchResult;
034:
035: import org.apache.commons.lang.StringUtils;
036: import org.apache.commons.logging.Log;
037: import org.apache.commons.logging.LogFactory;
038: import org.apache.jetspeed.security.SecurityException;
039: import org.apache.jetspeed.security.impl.UserPrincipalImpl;
040:
041: public class LdapMemberShipDaoImpl extends LdapPrincipalDaoImpl
042: implements LdapMembershipDao {
043:
044: /** The logger. */
045: private static final Log logger = LogFactory
046: .getLog(LdapMemberShipDaoImpl.class);
047:
048: public LdapMemberShipDaoImpl() throws SecurityException {
049: super ();
050: }
051:
052: public LdapMemberShipDaoImpl(LdapBindingConfig config)
053: throws SecurityException {
054: super (config);
055: }
056:
057: /* (non-Javadoc)
058: * @see org.apache.jetspeed.security.spi.impl.ldap.LdapMembershipDao#searchGroupMemberShipByGroup(java.lang.String, javax.naming.directory.SearchControls)
059: */
060: public String[] searchGroupMemberShipByGroup(
061: final String userPrincipalUid, SearchControls cons)
062: throws NamingException {
063:
064: String query = "(&(" + getGroupMembershipAttribute() + "="
065: + getUserDN(userPrincipalUid) + ")" + getGroupFilter()
066: + ")";
067:
068: if (logger.isDebugEnabled()) {
069: logger.debug("query[" + query + "]");
070: }
071:
072: cons.setSearchScope(getSearchScope());
073: String groupFilterBase = getGroupFilterBase();
074: NamingEnumeration searchResults = ((DirContext) ctx).search(
075: groupFilterBase, query, cons);
076:
077: List groupPrincipalUids = new ArrayList();
078: while (searchResults.hasMore()) {
079: SearchResult result = (SearchResult) searchResults.next();
080: Attributes answer = result.getAttributes();
081: groupPrincipalUids.addAll(getAttributes(getAttribute(
082: getGroupIdAttribute(), answer)));
083: }
084: return (String[]) groupPrincipalUids
085: .toArray(new String[groupPrincipalUids.size()]);
086:
087: }
088:
089: /* (non-Javadoc)
090: * @see org.apache.jetspeed.security.spi.impl.ldap.LdapMembershipDao#searchGroupMemberShipByUser(java.lang.String, javax.naming.directory.SearchControls)
091: */
092: public String[] searchGroupMemberShipByUser(
093: final String userPrincipalUid, SearchControls cons)
094: throws NamingException {
095: NamingEnumeration searchResults = searchByWildcardedUid(
096: userPrincipalUid, cons);
097:
098: if (!searchResults.hasMore()) {
099: throw new NamingException(
100: "Could not find any user with uid["
101: + userPrincipalUid + "]");
102: }
103:
104: Attributes userAttributes = getFirstUser(searchResults);
105: List groupUids = new ArrayList();
106: Attribute attr = getAttribute(
107: getUserGroupMembershipAttribute(), userAttributes);
108: List attrs = getAttributes(attr);
109: Iterator it = attrs.iterator();
110: while (it.hasNext()) {
111: String cnfull = (String) it.next();
112: if (cnfull.toLowerCase().indexOf(
113: getGroupFilterBase().toLowerCase()) != -1) {
114: String cn = extractLdapAttr(cnfull,
115: getRoleUidAttribute());
116: if (cn != null) {
117: groupUids.add(cn);
118: }
119: }
120: }
121: //List uids = getAttributes(getAttribute(getUserGroupMembershipAttribute(), userAttributes),getGroupFilterBase());
122: return (String[]) groupUids
123: .toArray(new String[groupUids.size()]);
124: }
125:
126: /* (non-Javadoc)
127: * @see org.apache.jetspeed.security.spi.impl.ldap.LdapMembershipDao#searchRoleMemberShipByRole(java.lang.String, javax.naming.directory.SearchControls)
128: */
129: public String[] searchRoleMemberShipByRole(
130: final String userPrincipalUid, SearchControls cons)
131: throws NamingException {
132:
133: String query = "(&(" + getRoleMembershipAttribute() + "="
134: + getUserDN(userPrincipalUid) + ")" + getRoleFilter()
135: + ")";
136:
137: if (logger.isDebugEnabled()) {
138: logger.debug("query[" + query + "]");
139: }
140:
141: cons.setSearchScope(getSearchScope());
142: NamingEnumeration searchResults = ((DirContext) ctx).search(
143: getRoleFilterBase(), query, cons);
144: List rolePrincipalUids = new ArrayList();
145: while (searchResults.hasMore()) {
146:
147: SearchResult result = (SearchResult) searchResults.next();
148: Attributes answer = result.getAttributes();
149: rolePrincipalUids.addAll(getAttributes(getAttribute(
150: getRoleIdAttribute(), answer)));
151: }
152: return (String[]) rolePrincipalUids
153: .toArray(new String[rolePrincipalUids.size()]);
154: }
155:
156: /* (non-Javadoc)
157: * @see org.apache.jetspeed.security.spi.impl.ldap.LdapMembershipDao#searchRoleMemberShipByUser(java.lang.String, javax.naming.directory.SearchControls)
158: */
159: public String[] searchRoleMemberShipByUser(
160: final String userPrincipalUid, SearchControls cons)
161: throws NamingException {
162:
163: NamingEnumeration results = searchByWildcardedUid(
164: userPrincipalUid, cons);
165:
166: if (!results.hasMore()) {
167: throw new NamingException(
168: "Could not find any user with uid["
169: + userPrincipalUid + "]");
170: }
171:
172: Attributes userAttributes = getFirstUser(results);
173: List newAttrs = new ArrayList();
174: Attribute attr = getAttribute(getUserRoleMembershipAttribute(),
175: userAttributes);
176: List attrs = getAttributes(attr);
177: Iterator it = attrs.iterator();
178: while (it.hasNext()) {
179: String cnfull = (String) it.next();
180: if (cnfull.toLowerCase().indexOf(
181: getRoleFilterBase().toLowerCase()) != -1) {
182: String cn = extractLdapAttr(cnfull,
183: getRoleUidAttribute());
184: if (cn != null) {
185: newAttrs.add(cn);
186: }
187: } else {
188: // No conversion required (I think!)
189: String cn = cnfull;
190: newAttrs.add(cn);
191: }
192: }
193: return (String[]) newAttrs.toArray(new String[newAttrs.size()]);
194: }
195:
196: /* (non-Javadoc)
197: * @see org.apache.jetspeed.security.spi.impl.ldap.LdapMembershipDao#searchUsersFromGroupByGroup(java.lang.String, javax.naming.directory.SearchControls)
198: */
199: public String[] searchUsersFromGroupByGroup(
200: final String groupPrincipalUid, SearchControls cons)
201: throws NamingException {
202:
203: String query = "(&(" + getGroupIdAttribute() + "="
204: + (groupPrincipalUid) + ")" + getGroupFilter() + ")";
205:
206: if (logger.isDebugEnabled()) {
207: logger.debug("query[" + query + "]");
208: }
209:
210: ArrayList userPrincipalUids = new ArrayList();
211:
212: cons.setSearchScope(getSearchScope());
213: NamingEnumeration results = ((DirContext) ctx).search(
214: getGroupFilterBase(), query, cons);
215:
216: while (results.hasMore()) {
217: SearchResult result = (SearchResult) results.next();
218: Attributes answer = result.getAttributes();
219:
220: List newAttrs = new ArrayList();
221:
222: Attribute userPrincipalUid = getAttribute(
223: getGroupMembershipAttribute(), answer);
224: List attrs = getAttributes(userPrincipalUid);
225: Iterator it = attrs.iterator();
226: while (it.hasNext()) {
227: String uidfull = (String) it.next();
228: if (!StringUtils.isEmpty(uidfull)) {
229: if (uidfull.toLowerCase().indexOf(
230: getUserFilterBase().toLowerCase()) != -1) {
231: String uid = extractLdapAttr(uidfull,
232: getUserIdAttribute());
233: if (uid != null) {
234: newAttrs.add(uid);
235: }
236: }
237: }
238: }
239: userPrincipalUids.addAll(newAttrs);
240: }
241: return (String[]) userPrincipalUids
242: .toArray(new String[userPrincipalUids.size()]);
243: }
244:
245: /* (non-Javadoc)
246: * @see org.apache.jetspeed.security.spi.impl.ldap.LdapMembershipDao#searchUsersFromGroupByUser(java.lang.String, javax.naming.directory.SearchControls)
247: */
248: public String[] searchUsersFromGroupByUser(
249: final String groupPrincipalUid, SearchControls cons)
250: throws NamingException {
251:
252: String query = "(&(" + getUserGroupMembershipAttribute() + "="
253: + getGroupDN(groupPrincipalUid) + ")" + getUserFilter()
254: + ")";
255: if (logger.isDebugEnabled()) {
256: logger.debug("query[" + query + "]");
257: }
258:
259: cons.setSearchScope(getSearchScope());
260: NamingEnumeration results = ((DirContext) ctx).search(
261: getUserFilterBase(), query, cons);
262:
263: ArrayList userPrincipalUids = new ArrayList();
264:
265: while (results.hasMore()) {
266: SearchResult result = (SearchResult) results.next();
267: Attributes answer = result.getAttributes();
268: userPrincipalUids.addAll(getAttributes(getAttribute(
269: getUserIdAttribute(), answer)));
270: }
271: return (String[]) userPrincipalUids
272: .toArray(new String[userPrincipalUids.size()]);
273: }
274:
275: public String[] searchRolesFromGroupByGroup(
276: final String groupPrincipalUid, SearchControls cons)
277: throws NamingException {
278:
279: String query = "(&(" + getGroupIdAttribute() + "="
280: + (groupPrincipalUid) + ")" + getGroupFilter() + ")";
281:
282: if (logger.isDebugEnabled()) {
283: logger.debug("query[" + query + "]");
284: }
285:
286: ArrayList rolePrincipalUids = new ArrayList();
287:
288: cons.setSearchScope(getSearchScope());
289: NamingEnumeration groups = ((DirContext) ctx).search(
290: getGroupFilterBase(), query, cons);
291:
292: while (groups.hasMore()) {
293: SearchResult group = (SearchResult) groups.next();
294: Attributes groupAttributes = group.getAttributes();
295:
296: Attribute rolesFromGroup = getAttribute(
297: getGroupMembershipForRoleAttribute(),
298: groupAttributes);
299: List roleDNs = getAttributes(rolesFromGroup,
300: getRoleFilterBase());
301: Iterator it = roleDNs.iterator();
302: while (it.hasNext()) {
303: String roleDN = (String) it.next();
304: if (!StringUtils.isEmpty(roleDN)) {
305: String roleId = extractLdapAttr(roleDN,
306: getRoleUidAttribute());
307: if (roleId != null) {
308: NamingEnumeration rolesResults = searchRoleByWildcardedUid(
309: roleId, cons);
310: if (rolesResults.hasMore())
311: if (rolesResults.nextElement() != null)
312: rolePrincipalUids.add(roleId);
313: }
314: }
315: }
316: }
317: return (String[]) rolePrincipalUids
318: .toArray(new String[rolePrincipalUids.size()]);
319: }
320:
321: /*
322: * (non-Javadoc)
323: *
324: * @see org.apache.jetspeed.security.spi.impl.ldap.LdapMembershipDao#searchUsersFromGroupByUser(java.lang.String,
325: * javax.naming.directory.SearchControls)
326: */
327: public String[] searchRolesFromGroupByRole(
328: final String groupPrincipalUid, SearchControls cons)
329: throws NamingException {
330:
331: String query = "(&(" + getRoleGroupMembershipForRoleAttribute()
332: + "=" + getGroupDN(groupPrincipalUid) + ")"
333: + getRoleFilter() + ")";
334:
335: if (logger.isDebugEnabled()) {
336: logger.debug("query[" + query + "]");
337: }
338:
339: cons.setSearchScope(getSearchScope());
340: NamingEnumeration results = ((DirContext) ctx).search(
341: getRoleFilterBase(), query, cons);
342:
343: ArrayList rolePrincipalUids = new ArrayList();
344:
345: while (results.hasMore()) {
346: SearchResult result = (SearchResult) results.next();
347: Attributes answer = result.getAttributes();
348: rolePrincipalUids.addAll(getAttributes(getAttribute(
349: getRoleIdAttribute(), answer)));
350: }
351: return (String[]) rolePrincipalUids
352: .toArray(new String[rolePrincipalUids.size()]);
353: }
354:
355: /* (non-Javadoc)
356: * @see org.apache.jetspeed.security.spi.impl.ldap.LdapMembershipDao#searchUsersFromRoleByRole(java.lang.String, javax.naming.directory.SearchControls)
357: */
358: public String[] searchUsersFromRoleByRole(
359: final String rolePrincipalUid, SearchControls cons)
360: throws NamingException {
361:
362: String query = "(&(" + getRoleIdAttribute() + "="
363: + (rolePrincipalUid) + ")" + getRoleFilter() + ")";
364:
365: if (logger.isDebugEnabled()) {
366: logger.debug("query[" + query + "]");
367: }
368:
369: ArrayList userPrincipalUids = new ArrayList();
370:
371: cons.setSearchScope(getSearchScope());
372: NamingEnumeration results = ((DirContext) ctx).search(
373: getRoleFilterBase(), query, cons);
374:
375: while (results.hasMore()) {
376: SearchResult result = (SearchResult) results.next();
377: Attributes answer = result.getAttributes();
378:
379: Attribute userPrincipalUid = getAttribute(
380: getRoleMembershipAttribute(), answer);
381: List attrs = getAttributes(userPrincipalUid);
382: Iterator it = attrs.iterator();
383: while (it.hasNext()) {
384: String uidfull = (String) it.next();
385: if (!StringUtils.isEmpty(uidfull)) {
386: String uid = extractLdapAttr(uidfull,
387: getUserIdAttribute());
388: if (uid != null) {
389: userPrincipalUids.add(uid);
390: }
391: }
392: }
393: }
394: return (String[]) userPrincipalUids
395: .toArray(new String[userPrincipalUids.size()]);
396: }
397:
398: /* (non-Javadoc)
399: * @see org.apache.jetspeed.security.spi.impl.ldap.LdapMembershipDao#searchUsersFromRoleByUser(java.lang.String, javax.naming.directory.SearchControls)
400: */
401: public String[] searchUsersFromRoleByUser(
402: final String rolePrincipalUid, SearchControls cons)
403: throws NamingException {
404: String roleMemberAttr = getUserRoleMembershipAttribute();
405: /*
406: * search for those users with a role membership attribute matching two possible values:
407: * - the role principal UID (e.g. 'admin') or
408: * - the full DN of the role (e.g. 'cn=admin,ou=Roles,o=sevenSeas')
409: */
410: StringBuffer byRolePrincipalUidMatch = new StringBuffer("(")
411: .append(roleMemberAttr).append("=").append(
412: rolePrincipalUid).append(")");
413: StringBuffer byRoleDNMatch = new StringBuffer("(").append(
414: roleMemberAttr).append("=").append(
415: getRoleDN(rolePrincipalUid, true)).append(")");
416:
417: StringBuffer completeRoleAttrMatch = new StringBuffer("(|")
418: .append(byRolePrincipalUidMatch).append(byRoleDNMatch)
419: .append(")");
420: StringBuffer query = new StringBuffer("(&").append(
421: completeRoleAttrMatch).append("(").append(
422: getUserFilter()).append("))");
423:
424: if (logger.isDebugEnabled()) {
425: logger.debug("query[" + query + "]");
426: }
427:
428: cons.setSearchScope(getSearchScope());
429: NamingEnumeration results = ((DirContext) ctx).search(
430: getUserFilterBase(), query.toString(), cons);
431:
432: ArrayList userPrincipalUids = new ArrayList();
433:
434: while (results.hasMore()) {
435: SearchResult result = (SearchResult) results.next();
436: Attributes answer = result.getAttributes();
437: userPrincipalUids.addAll(getAttributes(getAttribute(
438: getUserIdAttribute(), answer)));
439: }
440: return (String[]) userPrincipalUids
441: .toArray(new String[userPrincipalUids.size()]);
442: }
443:
444: /**
445: * @param attr
446: * @return
447: * @throws NamingException
448: */
449: protected List getAttributes(Attribute attr) throws NamingException {
450: return getAttributes(attr, null);
451: }
452:
453: /**
454: * @param attr
455: * @return
456: * @throws NamingException
457: */
458: protected List getAttributes(Attribute attr, String filter)
459: throws NamingException {
460: List uids = new ArrayList();
461: if (attr != null) {
462: Enumeration groupUidEnum = attr.getAll();
463: while (groupUidEnum.hasMoreElements()) {
464: String groupDN = (String) groupUidEnum.nextElement();
465: if (filter == null) {
466: uids.add(groupDN);
467: } else if (filter != null
468: && groupDN.toLowerCase().indexOf(
469: filter.toLowerCase()) != -1) {
470: uids.add(groupDN);
471: }
472: }
473: }
474: return uids;
475: }
476:
477: /**
478: * @param results
479: * @return
480: * @throws NamingException
481: */
482: private Attributes getFirstUser(NamingEnumeration results)
483: throws NamingException {
484: SearchResult result = (SearchResult) results.next();
485: Attributes answer = result.getAttributes();
486:
487: return answer;
488: }
489:
490: /**
491: * <p>
492: * A template method for defining the attributes for a particular LDAP class.
493: * </p>
494: *
495: * @param principalUid The principal uid.
496: * @return the LDAP attributes object for the particular class.
497: */
498: protected Attributes defineLdapAttributes(final String principalUid) {
499: Attributes attrs = new BasicAttributes(true);
500: BasicAttribute classes = new BasicAttribute("objectclass");
501:
502: classes.add("top");
503: classes.add("person");
504: classes.add("organizationalPerson");
505: classes.add("inetorgperson");
506: attrs.put(classes);
507: attrs.put("cn", principalUid);
508: attrs.put("sn", principalUid);
509:
510: return attrs;
511: }
512:
513: /**
514: * @see org.apache.jetspeed.security.spi.impl.ldap.LdapPrincipalDaoImpl#getDnSuffix()
515: */
516: protected String getDnSuffix() {
517: return this .getUserFilterBase();
518: }
519:
520: /**
521: * <p>
522: * Creates a GroupPrincipal object.
523: * </p>
524: *
525: * @param principalUid The principal uid.
526: * @return A group principal object.
527: */
528: protected Principal makePrincipal(String principalUid) {
529: return new UserPrincipalImpl(principalUid);
530: }
531:
532: private String extractLdapAttr(String dn, String ldapAttrName) {
533:
534: String dnLowerCase = dn.toLowerCase();
535: String ldapAttrNameLowerCase = ldapAttrName.toLowerCase();
536:
537: if (dnLowerCase.indexOf(ldapAttrNameLowerCase + "=") == -1)
538: return null;
539:
540: if (dn.indexOf(",") != -1
541: && dnLowerCase.indexOf(ldapAttrNameLowerCase + "=") != -1)
542: return dn.substring(dnLowerCase
543: .indexOf(ldapAttrNameLowerCase)
544: + ldapAttrName.length() + 1, dn.indexOf(","));
545: return dn.substring(dnLowerCase.indexOf(ldapAttrNameLowerCase)
546: + ldapAttrName.length() + 1, dn.length());
547: }
548:
549: protected String[] getObjectClasses() {
550: return this .getUserObjectClasses();
551: }
552:
553: protected String getUidAttributeForPrincipal() {
554: return this .getUserUidAttribute();
555: }
556:
557: protected String[] getAttributes() {
558: return getUserAttributes();
559: }
560:
561: protected String getEntryPrefix() {
562: return this .getUidAttribute();
563: }
564:
565: protected String getSearchSuffix() {
566: return this.getUserFilter();
567: }
568: }
|