001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.security.ldap;
016    
017    import com.liferay.portal.kernel.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    import com.liferay.portal.kernel.log.LogUtil;
020    import com.liferay.portal.kernel.util.ArrayUtil;
021    import com.liferay.portal.kernel.util.CharPool;
022    import com.liferay.portal.kernel.util.GetterUtil;
023    import com.liferay.portal.kernel.util.PropertiesUtil;
024    import com.liferay.portal.kernel.util.PropsKeys;
025    import com.liferay.portal.kernel.util.StringBundler;
026    import com.liferay.portal.kernel.util.StringPool;
027    import com.liferay.portal.kernel.util.StringUtil;
028    import com.liferay.portal.kernel.util.Validator;
029    import com.liferay.portal.model.CompanyConstants;
030    import com.liferay.portal.util.PrefsPropsUtil;
031    import com.liferay.portal.util.PropsUtil;
032    import com.liferay.portal.util.PropsValues;
033    
034    import java.util.ArrayList;
035    import java.util.List;
036    import java.util.Properties;
037    
038    import javax.naming.Binding;
039    import javax.naming.CompositeName;
040    import javax.naming.Context;
041    import javax.naming.Name;
042    import javax.naming.NameNotFoundException;
043    import javax.naming.NamingEnumeration;
044    import javax.naming.OperationNotSupportedException;
045    import javax.naming.directory.Attribute;
046    import javax.naming.directory.Attributes;
047    import javax.naming.directory.SearchControls;
048    import javax.naming.directory.SearchResult;
049    import javax.naming.ldap.Control;
050    import javax.naming.ldap.InitialLdapContext;
051    import javax.naming.ldap.LdapContext;
052    import javax.naming.ldap.PagedResultsControl;
053    import javax.naming.ldap.PagedResultsResponseControl;
054    
055    /**
056     * @author Michael Young
057     * @author Brian Wing Shun Chan
058     * @author Jerry Niu
059     * @author Scott Lee
060     * @author Hervé Ménage
061     * @author Samuel Kong
062     * @author Ryan Park
063     * @author Wesley Gong
064     * @author Marcellus Tavares
065     * @author Hugo Huijser
066     */
067    public class PortalLDAPUtil {
068    
069            public static LdapContext getContext(long ldapServerId, long companyId)
070                    throws Exception {
071    
072                    String postfix = LDAPSettingsUtil.getPropertyPostfix(ldapServerId);
073    
074                    String baseProviderURL = PrefsPropsUtil.getString(
075                            companyId, PropsKeys.LDAP_BASE_PROVIDER_URL + postfix);
076                    String pricipal = PrefsPropsUtil.getString(
077                            companyId, PropsKeys.LDAP_SECURITY_PRINCIPAL + postfix);
078                    String credentials = PrefsPropsUtil.getString(
079                            companyId, PropsKeys.LDAP_SECURITY_CREDENTIALS + postfix);
080    
081                    return getContext(companyId, baseProviderURL, pricipal, credentials);
082            }
083    
084            public static LdapContext getContext(
085                            long companyId, String providerURL, String principal,
086                            String credentials)
087                    throws Exception {
088    
089                    Properties environmentProperties = new Properties();
090    
091                    environmentProperties.put(
092                            Context.INITIAL_CONTEXT_FACTORY,
093                            PrefsPropsUtil.getString(
094                                    companyId, PropsKeys.LDAP_FACTORY_INITIAL));
095                    environmentProperties.put(Context.PROVIDER_URL, providerURL);
096                    environmentProperties.put(Context.SECURITY_PRINCIPAL, principal);
097                    environmentProperties.put(Context.SECURITY_CREDENTIALS, credentials);
098                    environmentProperties.put(
099                            Context.REFERRAL,
100                            PrefsPropsUtil.getString(companyId, PropsKeys.LDAP_REFERRAL));
101    
102                    Properties ldapConnectionProperties = PropsUtil.getProperties(
103                            PropsKeys.LDAP_CONNECTION_PROPERTY_PREFIX, true);
104    
105                    PropertiesUtil.merge(environmentProperties, ldapConnectionProperties);
106    
107                    LogUtil.debug(_log, environmentProperties);
108    
109                    LdapContext ldapContext = null;
110    
111                    try {
112                            ldapContext = new InitialLdapContext(environmentProperties, null);
113                    }
114                    catch (Exception e) {
115                            if (_log.isWarnEnabled()) {
116                                    _log.warn("Failed to bind to the LDAP server");
117                            }
118    
119                            if (_log.isDebugEnabled()) {
120                                    _log.debug(e, e);
121                            }
122                    }
123    
124                    return ldapContext;
125            }
126    
127            public static Binding getGroup(
128                            long ldapServerId, long companyId, String groupName)
129                    throws Exception {
130    
131                    String postfix = LDAPSettingsUtil.getPropertyPostfix(ldapServerId);
132    
133                    LdapContext ldapContext = getContext(ldapServerId, companyId);
134    
135                    NamingEnumeration<SearchResult> enu = null;
136    
137                    try {
138                            if (ldapContext == null) {
139                                    return null;
140                            }
141    
142                            String baseDN = PrefsPropsUtil.getString(
143                                    companyId, PropsKeys.LDAP_BASE_DN + postfix);
144    
145                            Properties groupMappings = LDAPSettingsUtil.getGroupMappings(
146                                    ldapServerId, companyId);
147    
148                            StringBundler filter = new StringBundler(5);
149    
150                            filter.append(StringPool.OPEN_PARENTHESIS);
151                            filter.append(groupMappings.getProperty("groupName"));
152                            filter.append(StringPool.EQUAL);
153                            filter.append(groupName);
154                            filter.append(StringPool.CLOSE_PARENTHESIS);
155    
156                            SearchControls searchControls = new SearchControls(
157                                    SearchControls.SUBTREE_SCOPE, 1, 0, null, false, false);
158    
159                            enu = ldapContext.search(baseDN, filter.toString(), searchControls);
160                    }
161                    catch (Exception e) {
162                            throw e;
163                    }
164                    finally {
165                            if (ldapContext != null) {
166                                    ldapContext.close();
167                            }
168                    }
169    
170                    if (enu.hasMoreElements()) {
171                            Binding binding = enu.nextElement();
172    
173                            enu.close();
174    
175                            return binding;
176                    }
177                    else {
178                            return null;
179                    }
180            }
181    
182            public static Attributes getGroupAttributes(
183                            long ldapServerId, long companyId, LdapContext ldapContext,
184                            String fullDistinguishedName)
185                    throws Exception {
186    
187                    return getGroupAttributes(ldapServerId, companyId, ldapContext,
188                            fullDistinguishedName, false);
189            }
190    
191            public static Attributes getGroupAttributes(
192                            long ldapServerId, long companyId, LdapContext ldapContext,
193                            String fullDistinguishedName, boolean includeReferenceAttributes)
194                    throws Exception {
195    
196                    Properties groupMappings = LDAPSettingsUtil.getGroupMappings(
197                            ldapServerId, companyId);
198    
199                    List<String> mappedGroupAttributeIds = new ArrayList<String>();
200    
201                    mappedGroupAttributeIds.add(groupMappings.getProperty("groupName"));
202                    mappedGroupAttributeIds.add(groupMappings.getProperty("description"));
203    
204                    if (includeReferenceAttributes) {
205                            mappedGroupAttributeIds.add(groupMappings.getProperty("user"));
206                    }
207    
208                    return _getAttributes(
209                            ldapContext, fullDistinguishedName,
210                            mappedGroupAttributeIds.toArray(new String[0]));
211            }
212    
213            public static byte[] getGroups(
214                            long companyId, LdapContext ldapContext, byte[] cookie,
215                            int maxResults, String baseDN, String groupFilter,
216                            List<SearchResult> searchResults)
217                    throws Exception {
218    
219                    return searchLDAP(
220                            companyId, ldapContext, cookie, maxResults, baseDN, groupFilter,
221                            null, searchResults);
222            }
223    
224            public static byte[] getGroups(
225                            long companyId, LdapContext ldapContext, byte[] cookie,
226                            int maxResults, String baseDN, String groupFilter,
227                            String[] attributeIds, List<SearchResult> searchResults)
228                    throws Exception {
229    
230                    return searchLDAP(
231                            companyId, ldapContext, cookie, maxResults, baseDN, groupFilter,
232                            attributeIds, searchResults);
233            }
234    
235            public static byte[] getGroups(
236                            long ldapServerId, long companyId, LdapContext ldapContext,
237                            byte[] cookie, int maxResults, List<SearchResult> searchResults)
238                    throws Exception {
239    
240                    String postfix = LDAPSettingsUtil.getPropertyPostfix(ldapServerId);
241    
242                    String baseDN = PrefsPropsUtil.getString(
243                            companyId, PropsKeys.LDAP_BASE_DN + postfix);
244                    String groupFilter = PrefsPropsUtil.getString(
245                            companyId, PropsKeys.LDAP_IMPORT_GROUP_SEARCH_FILTER + postfix);
246    
247                    return getGroups(
248                            companyId, ldapContext, cookie, maxResults, baseDN, groupFilter,
249                            searchResults);
250            }
251    
252            public static byte[] getGroups(
253                            long ldapServerId, long companyId, LdapContext ldapContext,
254                            byte[] cookie, int maxResults, String[] attributeIds,
255                            List<SearchResult> searchResults)
256                    throws Exception {
257    
258                    String postfix = LDAPSettingsUtil.getPropertyPostfix(ldapServerId);
259    
260                    String baseDN = PrefsPropsUtil.getString(
261                            companyId, PropsKeys.LDAP_BASE_DN + postfix);
262                    String groupFilter = PrefsPropsUtil.getString(
263                            companyId, PropsKeys.LDAP_IMPORT_GROUP_SEARCH_FILTER + postfix);
264    
265                    return getGroups(
266                            companyId, ldapContext, cookie, maxResults, baseDN, groupFilter,
267                            attributeIds, searchResults);
268            }
269    
270            public static String getGroupsDN(long ldapServerId, long companyId)
271                    throws Exception {
272    
273                    String postfix = LDAPSettingsUtil.getPropertyPostfix(ldapServerId);
274    
275                    return PrefsPropsUtil.getString(
276                            companyId, PropsKeys.LDAP_GROUPS_DN + postfix);
277            }
278    
279            public static long getLdapServerId(
280                            long companyId, String screenName, String emailAddress)
281                    throws Exception {
282    
283                    long[] ldapServerIds = StringUtil.split(
284                            PrefsPropsUtil.getString(companyId, "ldap.server.ids"), 0L);
285    
286                    for (long ldapServerId : ldapServerIds) {
287                            if (hasUser(ldapServerId, companyId, screenName, emailAddress)) {
288                                    return ldapServerId;
289                            }
290                    }
291    
292                    boolean hasProperties = false;
293    
294                    for (int ldapServerId = 0;; ldapServerId++) {
295                            String postfix = LDAPSettingsUtil.getPropertyPostfix(ldapServerId);
296    
297                            String providerUrl = PrefsPropsUtil.getString(
298                                    companyId, PropsKeys.LDAP_BASE_PROVIDER_URL + postfix);
299    
300                            if (Validator.isNull(providerUrl)) {
301                                    break;
302                            }
303    
304                            hasProperties = true;
305    
306                            if (hasUser(ldapServerId, companyId, screenName, emailAddress)) {
307                                    return ldapServerId;
308                            }
309                    }
310    
311                    if (hasProperties || (ldapServerIds.length <= 0)) {
312                            return 0;
313                    }
314    
315                    return ldapServerIds[0];
316            }
317    
318            public static Attribute getMultivaluedAttribute(
319                            long companyId, LdapContext ldapContext, String baseDN,
320                            String filter, Attribute attribute)
321                    throws Exception {
322    
323                    if (attribute.size() > 0) {
324                            return attribute;
325                    }
326    
327                    String[] attributeIds = {_getNextRange(attribute.getID())};
328    
329                    while (true) {
330                            List<SearchResult> searchResults = new ArrayList<SearchResult>();
331    
332                            searchLDAP(
333                                    companyId, ldapContext, new byte[0], 0, baseDN, filter,
334                                    attributeIds, searchResults);
335    
336                            if (searchResults.size() != 1) {
337                                    break;
338                            }
339    
340                            SearchResult searchResult = searchResults.get(0);
341    
342                            Attributes attributes = searchResult.getAttributes();
343    
344                            if (attributes.size() != 1) {
345                                    break;
346                            }
347    
348                            NamingEnumeration<? extends Attribute> enu = attributes.getAll();
349    
350                            if (!enu.hasMoreElements()) {
351                                    break;
352                            }
353    
354                            Attribute curAttribute = enu.nextElement();
355    
356                            for (int i = 0; i < curAttribute.size(); i++) {
357                                    attribute.add(curAttribute.get(i));
358                            }
359    
360                            if (StringUtil.endsWith(curAttribute.getID(), StringPool.STAR) ||
361                                    (curAttribute.size() < PropsValues.LDAP_RANGE_SIZE)) {
362    
363                                    break;
364                            }
365    
366                            attributeIds[0] = _getNextRange(attributeIds[0]);
367                    }
368    
369                    return attribute;
370            }
371    
372            public static String getNameInNamespace(
373                            long ldapServerId, long companyId, Binding binding)
374                    throws Exception {
375    
376                    String postfix = LDAPSettingsUtil.getPropertyPostfix(ldapServerId);
377    
378                    String baseDN = PrefsPropsUtil.getString(
379                            companyId, PropsKeys.LDAP_BASE_DN + postfix);
380    
381                    String name = binding.getName();
382    
383                    if (name.startsWith(StringPool.QUOTE) &&
384                            name.endsWith(StringPool.QUOTE)) {
385    
386                            name = name.substring(1, name.length() - 1);
387                    }
388    
389                    if (Validator.isNull(baseDN)) {
390                            return name.toString();
391                    }
392                    else {
393                            return name.concat(StringPool.COMMA).concat(baseDN);
394                    }
395            }
396    
397            public static Binding getUser(
398                            long ldapServerId, long companyId, String screenName,
399                            String emailAddress)
400                    throws Exception {
401    
402                    String postfix = LDAPSettingsUtil.getPropertyPostfix(ldapServerId);
403    
404                    LdapContext ldapContext = getContext(ldapServerId, companyId);
405    
406                    NamingEnumeration<SearchResult> enu = null;
407    
408                    try {
409                            if (ldapContext == null) {
410                                    return null;
411                            }
412    
413                            String baseDN = PrefsPropsUtil.getString(
414                                    companyId, PropsKeys.LDAP_BASE_DN + postfix);
415    
416                            String filter = null;
417    
418                            String userFilter = PrefsPropsUtil.getString(
419                                    companyId, PropsKeys.LDAP_IMPORT_USER_SEARCH_FILTER + postfix);
420    
421                            Properties userMappings = LDAPSettingsUtil.getUserMappings(
422                                    ldapServerId, companyId);
423    
424                            String login = null;
425                            String loginMapping = null;
426    
427                            String authType = PrefsPropsUtil.getString(
428                                    companyId, PropsKeys.COMPANY_SECURITY_AUTH_TYPE,
429                                    PropsValues.COMPANY_SECURITY_AUTH_TYPE);
430    
431                            if (authType.equals(CompanyConstants.AUTH_TYPE_SN) &&
432                                    !PrefsPropsUtil.getBoolean(
433                                            companyId,
434                                            PropsKeys.USERS_SCREEN_NAME_ALWAYS_AUTOGENERATE)) {
435    
436                                    login = screenName;
437                                    loginMapping = userMappings.getProperty("screenName");
438                            }
439                            else {
440                                    login = emailAddress;
441                                    loginMapping = userMappings.getProperty("emailAddress");
442                            }
443    
444                            if (Validator.isNotNull(userFilter)) {
445                                    StringBundler sb = new StringBundler(11);
446    
447                                    sb.append(StringPool.OPEN_PARENTHESIS);
448                                    sb.append(StringPool.AMPERSAND);
449                                    sb.append(StringPool.OPEN_PARENTHESIS);
450                                    sb.append(loginMapping);
451                                    sb.append(StringPool.EQUAL);
452                                    sb.append(login);
453                                    sb.append(StringPool.CLOSE_PARENTHESIS);
454                                    sb.append(StringPool.OPEN_PARENTHESIS);
455                                    sb.append(userFilter);
456                                    sb.append(StringPool.CLOSE_PARENTHESIS);
457                                    sb.append(StringPool.CLOSE_PARENTHESIS);
458    
459                                    filter = sb.toString();
460                            }
461                            else {
462                                    StringBundler sb = new StringBundler(5);
463    
464                                    sb.append(StringPool.OPEN_PARENTHESIS);
465                                    sb.append(loginMapping);
466                                    sb.append(StringPool.EQUAL);
467                                    sb.append(login);
468                                    sb.append(StringPool.CLOSE_PARENTHESIS);
469    
470                                    filter = sb.toString();
471                            }
472    
473                            SearchControls searchControls = new SearchControls(
474                                    SearchControls.SUBTREE_SCOPE, 1, 0, null, false, false);
475    
476                            enu = ldapContext.search(baseDN, filter, searchControls);
477                    }
478                    catch (Exception e) {
479                            throw e;
480                    }
481                    finally {
482                            if (ldapContext != null) {
483                                    ldapContext.close();
484                            }
485                    }
486    
487                    if (enu.hasMoreElements()) {
488                            Binding binding = enu.nextElement();
489    
490                            enu.close();
491    
492                            return binding;
493                    }
494                    else {
495                            return null;
496                    }
497            }
498    
499            public static Attributes getUserAttributes(
500                            long ldapServerId, long companyId, LdapContext ldapContext,
501                            String fullDistinguishedName)
502                    throws Exception {
503    
504                    Properties userMappings = LDAPSettingsUtil.getUserMappings(
505                            ldapServerId, companyId);
506                    Properties userExpandoMappings =
507                            LDAPSettingsUtil.getUserExpandoMappings(ldapServerId, companyId);
508    
509                    PropertiesUtil.merge(userMappings, userExpandoMappings);
510    
511                    Properties contactMappings = LDAPSettingsUtil.getContactMappings(
512                            ldapServerId, companyId);
513                    Properties contactExpandoMappings =
514                            LDAPSettingsUtil.getContactExpandoMappings(ldapServerId, companyId);
515    
516                    PropertiesUtil.merge(contactMappings, contactExpandoMappings);
517    
518                    PropertiesUtil.merge(userMappings, contactMappings);
519    
520                    String[] mappedUserAttributeIds = ArrayUtil.toStringArray(
521                            userMappings.values().toArray(new Object[userMappings.size()]));
522    
523                    return _getAttributes(
524                            ldapContext, fullDistinguishedName, mappedUserAttributeIds);
525            }
526    
527            public static byte[] getUsers(
528                            long companyId, LdapContext ldapContext, byte[] cookie,
529                            int maxResults, String baseDN, String userFilter,
530                            List<SearchResult> searchResults)
531                    throws Exception {
532    
533                    return searchLDAP(
534                            companyId, ldapContext, cookie, maxResults, baseDN, userFilter,
535                            null, searchResults);
536            }
537    
538            public static byte[] getUsers(
539                            long companyId, LdapContext ldapContext, byte[] cookie,
540                            int maxResults, String baseDN, String userFilter,
541                            String[] attributeIds, List<SearchResult> searchResults)
542                    throws Exception {
543    
544                    return searchLDAP(
545                            companyId, ldapContext, cookie, maxResults, baseDN, userFilter,
546                            attributeIds, searchResults);
547            }
548    
549            public static byte[] getUsers(
550                            long ldapServerId, long companyId, LdapContext ldapContext,
551                            byte[] cookie, int maxResults, List<SearchResult> searchResults)
552                    throws Exception {
553    
554                    String postfix = LDAPSettingsUtil.getPropertyPostfix(ldapServerId);
555    
556                    String baseDN = PrefsPropsUtil.getString(
557                            companyId, PropsKeys.LDAP_BASE_DN + postfix);
558                    String userFilter = PrefsPropsUtil.getString(
559                            companyId, PropsKeys.LDAP_IMPORT_USER_SEARCH_FILTER + postfix);
560    
561                    return getUsers(
562                            companyId, ldapContext, cookie, maxResults, baseDN, userFilter,
563                            searchResults);
564            }
565    
566            public static byte[] getUsers(
567                            long ldapServerId, long companyId, LdapContext ldapContext,
568                            byte[] cookie, int maxResults, String[] attributeIds,
569                            List<SearchResult> searchResults)
570                    throws Exception {
571    
572                    String postfix = LDAPSettingsUtil.getPropertyPostfix(ldapServerId);
573    
574                    String baseDN = PrefsPropsUtil.getString(
575                            companyId, PropsKeys.LDAP_BASE_DN + postfix);
576                    String userFilter = PrefsPropsUtil.getString(
577                            companyId, PropsKeys.LDAP_IMPORT_USER_SEARCH_FILTER + postfix);
578    
579                    return getUsers(
580                            companyId, ldapContext, cookie, maxResults, baseDN, userFilter,
581                            attributeIds, searchResults);
582            }
583    
584            public static String getUsersDN(long ldapServerId, long companyId)
585                    throws Exception {
586    
587                    String postfix = LDAPSettingsUtil.getPropertyPostfix(ldapServerId);
588    
589                    return PrefsPropsUtil.getString(
590                            companyId, PropsKeys.LDAP_USERS_DN + postfix);
591            }
592    
593            public static boolean hasUser(
594                            long ldapServerId, long companyId, String screenName,
595                            String emailAddress)
596                    throws Exception {
597    
598                    if (getUser(
599                                    ldapServerId, companyId, screenName, emailAddress) != null) {
600    
601                            return true;
602                    }
603                    else {
604                            return false;
605                    }
606            }
607    
608            public static boolean isGroupMember(
609                            long ldapServerId, long companyId, String groupDN, String userDN)
610                    throws Exception {
611    
612                    LdapContext ldapContext = getContext(ldapServerId, companyId);
613    
614                    try {
615                            if (ldapContext == null) {
616                                    return false;
617                            }
618    
619                            Properties groupMappings = LDAPSettingsUtil.getGroupMappings(
620                                    ldapServerId, companyId);
621    
622                            StringBundler filter = new StringBundler(5);
623    
624                            filter.append(StringPool.OPEN_PARENTHESIS);
625                            filter.append(groupMappings.getProperty(GroupConverterKeys.USER));
626                            filter.append(StringPool.EQUAL);
627                            filter.append(userDN);
628                            filter.append(StringPool.CLOSE_PARENTHESIS);
629    
630                            SearchControls searchControls = new SearchControls(
631                                    SearchControls.SUBTREE_SCOPE, 1, 0, null, false, false);
632    
633                            NamingEnumeration<SearchResult> enu = ldapContext.search(
634                                    groupDN, filter.toString(), searchControls);
635    
636                            if (enu.hasMoreElements()) {
637                                    return true;
638                            }
639                    }
640                    catch (NameNotFoundException nnfe) {
641                            if (_log.isWarnEnabled()) {
642                                    _log.warn(
643                                            "Unable to determine if user DN " + userDN +
644                                                    " is a member of group DN " + groupDN,
645                                            nnfe);
646                            }
647                    }
648                    finally {
649                            if (ldapContext != null) {
650                                    ldapContext.close();
651                            }
652                    }
653    
654                    return false;
655            }
656    
657            public static boolean isUserGroupMember(
658                            long ldapServerId, long companyId, String groupDN, String userDN)
659                    throws Exception {
660    
661                    LdapContext ldapContext = getContext(ldapServerId, companyId);
662    
663                    try {
664                            if (ldapContext == null) {
665                                    return false;
666                            }
667    
668                            Properties userMappings = LDAPSettingsUtil.getUserMappings(
669                                    ldapServerId, companyId);
670    
671                            StringBundler filter = new StringBundler(5);
672    
673                            filter.append(StringPool.OPEN_PARENTHESIS);
674                            filter.append(userMappings.getProperty(UserConverterKeys.GROUP));
675                            filter.append(StringPool.EQUAL);
676                            filter.append(groupDN);
677                            filter.append(StringPool.CLOSE_PARENTHESIS);
678    
679                            SearchControls searchControls = new SearchControls(
680                                    SearchControls.SUBTREE_SCOPE, 1, 0, null, false, false);
681    
682                            NamingEnumeration<SearchResult> enu = ldapContext.search(
683                                    userDN, filter.toString(), searchControls);
684    
685                            if (enu.hasMoreElements()) {
686                                    return true;
687                            }
688                    }
689                    catch (NameNotFoundException nnfe) {
690                            if (_log.isWarnEnabled()) {
691                                    _log.warn(
692                                            "Unable to determine if group DN " + groupDN +
693                                                    " is a member of user DN " + userDN,
694                                            nnfe);
695                            }
696                    }
697                    finally {
698                            if (ldapContext != null) {
699                                    ldapContext.close();
700                            }
701                    }
702    
703                    return false;
704            }
705    
706            public static byte[] searchLDAP(
707                            long companyId, LdapContext ldapContext, byte[] cookie,
708                            int maxResults, String baseDN, String filter, String[] attributeIds,
709                            List<SearchResult> searchResults)
710                    throws Exception {
711    
712                    SearchControls searchControls = new SearchControls(
713                            SearchControls.SUBTREE_SCOPE, maxResults, 0, attributeIds, false,
714                            false);
715    
716                    try {
717                            if (cookie != null) {
718                                    if (cookie.length == 0) {
719                                            ldapContext.setRequestControls(
720                                                    new Control[] {
721                                                            new PagedResultsControl(
722                                                                    PropsValues.LDAP_PAGE_SIZE, Control.CRITICAL)
723                                                    });
724                                    }
725                                    else {
726                                            ldapContext.setRequestControls(
727                                                    new Control[] {
728                                                            new PagedResultsControl(
729                                                                    PropsValues.LDAP_PAGE_SIZE, cookie,
730                                                                    Control.CRITICAL)
731                                                    });
732                                    }
733    
734                                    NamingEnumeration<SearchResult> enu = ldapContext.search(
735                                            baseDN, filter, searchControls);
736    
737                                    while (enu.hasMoreElements()) {
738                                            searchResults.add(enu.nextElement());
739                                    }
740    
741                                    enu.close();
742    
743                                    return _getCookie(ldapContext.getResponseControls());
744                            }
745                    }
746                    catch (OperationNotSupportedException onse) {
747                            ldapContext.setRequestControls(null);
748    
749                            NamingEnumeration<SearchResult> enu = ldapContext.search(
750                                    baseDN, filter, searchControls);
751    
752                            while (enu.hasMoreElements()) {
753                                    searchResults.add(enu.nextElement());
754                            }
755    
756                            enu.close();
757                    }
758                    finally {
759                            ldapContext.setRequestControls(null);
760                    }
761    
762                    return null;
763            }
764    
765            private static Attributes _getAttributes(
766                            LdapContext ldapContext, String fullDistinguishedName,
767                            String[] attributeIds)
768                    throws Exception {
769    
770                    Name fullDN = new CompositeName().add(fullDistinguishedName);
771    
772                    Attributes attributes = null;
773    
774                    String[] auditAttributeIds = {
775                            "creatorsName", "createTimestamp", "modifiersName",
776                            "modifyTimestamp"
777                    };
778    
779                    if (attributeIds == null) {
780    
781                            // Get complete listing of LDAP attributes (slow)
782    
783                            attributes = ldapContext.getAttributes(fullDN);
784    
785                            NamingEnumeration<? extends Attribute> enu =
786                                    ldapContext.getAttributes(fullDN, auditAttributeIds).getAll();
787    
788                            while (enu.hasMoreElements()) {
789                                    attributes.put(enu.nextElement());
790                            }
791    
792                            enu.close();
793                    }
794                    else {
795    
796                            // Get specified LDAP attributes
797    
798                            int attributeCount = attributeIds.length + auditAttributeIds.length;
799    
800                            String[] allAttributeIds = new String[attributeCount];
801    
802                            System.arraycopy(
803                                    attributeIds, 0, allAttributeIds, 0, attributeIds.length);
804                            System.arraycopy(
805                                    auditAttributeIds, 0, allAttributeIds, attributeIds.length,
806                                    auditAttributeIds.length);
807    
808                            attributes = ldapContext.getAttributes(fullDN, allAttributeIds);
809                    }
810    
811                    return attributes;
812            }
813    
814            private static byte[] _getCookie(Control[] controls) {
815                    if (controls == null) {
816                            return null;
817                    }
818    
819                    for (Control control : controls) {
820                            if (control instanceof PagedResultsResponseControl) {
821                                    PagedResultsResponseControl pagedResultsResponseControl =
822                                            (PagedResultsResponseControl)control;
823    
824                                    return pagedResultsResponseControl.getCookie();
825                            }
826                    }
827    
828                    return null;
829            }
830    
831            private static String _getNextRange(String attributeId) {
832                    String originalAttributeId = null;
833                    int start = 0;
834                    int end = 0;
835    
836                    int x = attributeId.indexOf(CharPool.SEMICOLON);
837    
838                    if (x < 0) {
839                            originalAttributeId = attributeId;
840                            end = PropsValues.LDAP_RANGE_SIZE - 1;
841                    }
842                    else {
843                            int y = attributeId.indexOf(CharPool.EQUAL, x);
844                            int z = attributeId.indexOf(CharPool.DASH, y);
845    
846                            originalAttributeId = attributeId.substring(0, x);
847                            start = GetterUtil.getInteger(attributeId.substring(y + 1, z));
848                            end = GetterUtil.getInteger(attributeId.substring(z + 1));
849    
850                            start += PropsValues.LDAP_RANGE_SIZE;
851                            end += PropsValues.LDAP_RANGE_SIZE;
852                    }
853    
854                    StringBundler sb = new StringBundler(6);
855    
856                    sb.append(originalAttributeId);
857                    sb.append(StringPool.SEMICOLON);
858                    sb.append("range=");
859                    sb.append(start);
860                    sb.append(StringPool.DASH);
861                    sb.append(end);
862    
863                    return sb.toString();
864            }
865    
866            private static Log _log = LogFactoryUtil.getLog(PortalLDAPUtil.class);
867    
868    }