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                            if (enu.hasMoreElements()) {
162                                    Binding binding = enu.nextElement();
163    
164                                    return binding;
165                            }
166    
167                            return null;
168                    }
169                    finally {
170                            if (enu != null) {
171                                    enu.close();
172                            }
173    
174                            if (ldapContext != null) {
175                                    ldapContext.close();
176                            }
177                    }
178            }
179    
180            public static Attributes getGroupAttributes(
181                            long ldapServerId, long companyId, LdapContext ldapContext,
182                            String fullDistinguishedName)
183                    throws Exception {
184    
185                    return getGroupAttributes(
186                            ldapServerId, companyId, ldapContext, fullDistinguishedName, false);
187            }
188    
189            public static Attributes getGroupAttributes(
190                            long ldapServerId, long companyId, LdapContext ldapContext,
191                            String fullDistinguishedName, boolean includeReferenceAttributes)
192                    throws Exception {
193    
194                    Properties groupMappings = LDAPSettingsUtil.getGroupMappings(
195                            ldapServerId, companyId);
196    
197                    List<String> mappedGroupAttributeIds = new ArrayList<String>();
198    
199                    mappedGroupAttributeIds.add(groupMappings.getProperty("groupName"));
200                    mappedGroupAttributeIds.add(groupMappings.getProperty("description"));
201    
202                    if (includeReferenceAttributes) {
203                            mappedGroupAttributeIds.add(groupMappings.getProperty("user"));
204                    }
205    
206                    return _getAttributes(
207                            ldapContext, fullDistinguishedName,
208                            mappedGroupAttributeIds.toArray(
209                                    new String[mappedGroupAttributeIds.size()]));
210            }
211    
212            public static byte[] getGroups(
213                            long companyId, LdapContext ldapContext, byte[] cookie,
214                            int maxResults, String baseDN, String groupFilter,
215                            List<SearchResult> searchResults)
216                    throws Exception {
217    
218                    return searchLDAP(
219                            companyId, ldapContext, cookie, maxResults, baseDN, groupFilter,
220                            null, searchResults);
221            }
222    
223            public static byte[] getGroups(
224                            long companyId, LdapContext ldapContext, byte[] cookie,
225                            int maxResults, String baseDN, String groupFilter,
226                            String[] attributeIds, List<SearchResult> searchResults)
227                    throws Exception {
228    
229                    return searchLDAP(
230                            companyId, ldapContext, cookie, maxResults, baseDN, groupFilter,
231                            attributeIds, searchResults);
232            }
233    
234            public static byte[] getGroups(
235                            long ldapServerId, long companyId, LdapContext ldapContext,
236                            byte[] cookie, int maxResults, List<SearchResult> searchResults)
237                    throws Exception {
238    
239                    String postfix = LDAPSettingsUtil.getPropertyPostfix(ldapServerId);
240    
241                    String baseDN = PrefsPropsUtil.getString(
242                            companyId, PropsKeys.LDAP_BASE_DN + postfix);
243                    String groupFilter = PrefsPropsUtil.getString(
244                            companyId, PropsKeys.LDAP_IMPORT_GROUP_SEARCH_FILTER + postfix);
245    
246                    return getGroups(
247                            companyId, ldapContext, cookie, maxResults, baseDN, groupFilter,
248                            searchResults);
249            }
250    
251            public static byte[] getGroups(
252                            long ldapServerId, long companyId, LdapContext ldapContext,
253                            byte[] cookie, int maxResults, String[] attributeIds,
254                            List<SearchResult> searchResults)
255                    throws Exception {
256    
257                    String postfix = LDAPSettingsUtil.getPropertyPostfix(ldapServerId);
258    
259                    String baseDN = PrefsPropsUtil.getString(
260                            companyId, PropsKeys.LDAP_BASE_DN + postfix);
261                    String groupFilter = PrefsPropsUtil.getString(
262                            companyId, PropsKeys.LDAP_IMPORT_GROUP_SEARCH_FILTER + postfix);
263    
264                    return getGroups(
265                            companyId, ldapContext, cookie, maxResults, baseDN, groupFilter,
266                            attributeIds, searchResults);
267            }
268    
269            public static String getGroupsDN(long ldapServerId, long companyId)
270                    throws Exception {
271    
272                    String postfix = LDAPSettingsUtil.getPropertyPostfix(ldapServerId);
273    
274                    return PrefsPropsUtil.getString(
275                            companyId, PropsKeys.LDAP_GROUPS_DN + postfix);
276            }
277    
278            public static long getLdapServerId(
279                            long companyId, String screenName, String emailAddress)
280                    throws Exception {
281    
282                    long[] ldapServerIds = StringUtil.split(
283                            PrefsPropsUtil.getString(companyId, "ldap.server.ids"), 0L);
284    
285                    for (long ldapServerId : ldapServerIds) {
286                            if (hasUser(ldapServerId, companyId, screenName, emailAddress)) {
287                                    return ldapServerId;
288                            }
289                    }
290    
291                    boolean hasProperties = false;
292    
293                    for (int ldapServerId = 0;; ldapServerId++) {
294                            String postfix = LDAPSettingsUtil.getPropertyPostfix(ldapServerId);
295    
296                            String providerUrl = PrefsPropsUtil.getString(
297                                    companyId, PropsKeys.LDAP_BASE_PROVIDER_URL + postfix);
298    
299                            if (Validator.isNull(providerUrl)) {
300                                    break;
301                            }
302    
303                            hasProperties = true;
304    
305                            if (hasUser(ldapServerId, companyId, screenName, emailAddress)) {
306                                    return ldapServerId;
307                            }
308                    }
309    
310                    if (hasProperties || (ldapServerIds.length <= 0)) {
311                            return 0;
312                    }
313    
314                    return ldapServerIds[0];
315            }
316    
317            public static Attribute getMultivaluedAttribute(
318                            long companyId, LdapContext ldapContext, String baseDN,
319                            String filter, Attribute attribute)
320                    throws Exception {
321    
322                    if (attribute.size() > 0) {
323                            return attribute;
324                    }
325    
326                    String[] attributeIds = {_getNextRange(attribute.getID())};
327    
328                    while (true) {
329                            List<SearchResult> searchResults = new ArrayList<SearchResult>();
330    
331                            searchLDAP(
332                                    companyId, ldapContext, new byte[0], 0, baseDN, filter,
333                                    attributeIds, searchResults);
334    
335                            if (searchResults.size() != 1) {
336                                    break;
337                            }
338    
339                            SearchResult searchResult = searchResults.get(0);
340    
341                            Attributes attributes = searchResult.getAttributes();
342    
343                            if (attributes.size() != 1) {
344                                    break;
345                            }
346    
347                            NamingEnumeration<? extends Attribute> enu = null;
348    
349                            try {
350                                    enu = attributes.getAll();
351    
352                                    if (!enu.hasMoreElements()) {
353                                            break;
354                                    }
355    
356                                    Attribute curAttribute = enu.nextElement();
357    
358                                    for (int i = 0; i < curAttribute.size(); i++) {
359                                            attribute.add(curAttribute.get(i));
360                                    }
361    
362                                    if (StringUtil.endsWith(
363                                                    curAttribute.getID(), StringPool.STAR) ||
364                                            (curAttribute.size() < PropsValues.LDAP_RANGE_SIZE)) {
365    
366                                            break;
367                                    }
368                            }
369                            finally {
370                                    if (enu != null) {
371                                            enu.close();
372                                    }
373                            }
374    
375                            attributeIds[0] = _getNextRange(attributeIds[0]);
376                    }
377    
378                    return attribute;
379            }
380    
381            public static String getNameInNamespace(
382                            long ldapServerId, long companyId, Binding binding)
383                    throws Exception {
384    
385                    String postfix = LDAPSettingsUtil.getPropertyPostfix(ldapServerId);
386    
387                    String baseDN = PrefsPropsUtil.getString(
388                            companyId, PropsKeys.LDAP_BASE_DN + postfix);
389    
390                    String name = binding.getName();
391    
392                    if (name.startsWith(StringPool.QUOTE) &&
393                            name.endsWith(StringPool.QUOTE)) {
394    
395                            name = name.substring(1, name.length() - 1);
396                    }
397    
398                    if (Validator.isNull(baseDN)) {
399                            return name.toString();
400                    }
401                    else {
402                            return name.concat(StringPool.COMMA).concat(baseDN);
403                    }
404            }
405    
406            public static Binding getUser(
407                            long ldapServerId, long companyId, String screenName,
408                            String emailAddress)
409                    throws Exception {
410    
411                    String postfix = LDAPSettingsUtil.getPropertyPostfix(ldapServerId);
412    
413                    LdapContext ldapContext = getContext(ldapServerId, companyId);
414    
415                    NamingEnumeration<SearchResult> enu = null;
416    
417                    try {
418                            if (ldapContext == null) {
419                                    return null;
420                            }
421    
422                            String baseDN = PrefsPropsUtil.getString(
423                                    companyId, PropsKeys.LDAP_BASE_DN + postfix);
424    
425                            String filter = null;
426    
427                            String userFilter = PrefsPropsUtil.getString(
428                                    companyId, PropsKeys.LDAP_IMPORT_USER_SEARCH_FILTER + postfix);
429    
430                            Properties userMappings = LDAPSettingsUtil.getUserMappings(
431                                    ldapServerId, companyId);
432    
433                            String login = null;
434                            String loginMapping = null;
435    
436                            String authType = PrefsPropsUtil.getString(
437                                    companyId, PropsKeys.COMPANY_SECURITY_AUTH_TYPE,
438                                    PropsValues.COMPANY_SECURITY_AUTH_TYPE);
439    
440                            if (authType.equals(CompanyConstants.AUTH_TYPE_SN) &&
441                                    !PrefsPropsUtil.getBoolean(
442                                            companyId,
443                                            PropsKeys.USERS_SCREEN_NAME_ALWAYS_AUTOGENERATE)) {
444    
445                                    login = screenName;
446                                    loginMapping = userMappings.getProperty("screenName");
447                            }
448                            else {
449                                    login = emailAddress;
450                                    loginMapping = userMappings.getProperty("emailAddress");
451                            }
452    
453                            if (Validator.isNotNull(userFilter)) {
454                                    StringBundler sb = new StringBundler(11);
455    
456                                    sb.append(StringPool.OPEN_PARENTHESIS);
457                                    sb.append(StringPool.AMPERSAND);
458                                    sb.append(StringPool.OPEN_PARENTHESIS);
459                                    sb.append(loginMapping);
460                                    sb.append(StringPool.EQUAL);
461                                    sb.append(login);
462                                    sb.append(StringPool.CLOSE_PARENTHESIS);
463                                    sb.append(StringPool.OPEN_PARENTHESIS);
464                                    sb.append(userFilter);
465                                    sb.append(StringPool.CLOSE_PARENTHESIS);
466                                    sb.append(StringPool.CLOSE_PARENTHESIS);
467    
468                                    filter = sb.toString();
469                            }
470                            else {
471                                    StringBundler sb = new StringBundler(5);
472    
473                                    sb.append(StringPool.OPEN_PARENTHESIS);
474                                    sb.append(loginMapping);
475                                    sb.append(StringPool.EQUAL);
476                                    sb.append(login);
477                                    sb.append(StringPool.CLOSE_PARENTHESIS);
478    
479                                    filter = sb.toString();
480                            }
481    
482                            SearchControls searchControls = new SearchControls(
483                                    SearchControls.SUBTREE_SCOPE, 1, 0, null, false, false);
484    
485                            enu = ldapContext.search(baseDN, filter, searchControls);
486    
487                            if (enu.hasMoreElements()) {
488                                    Binding binding = enu.nextElement();
489    
490                                    return binding;
491                            }
492    
493                            return null;
494                    }
495                    finally {
496                            if (enu != null) {
497                                    enu.close();
498                            }
499    
500                            if (ldapContext != null) {
501                                    ldapContext.close();
502                            }
503                    }
504            }
505    
506            public static Attributes getUserAttributes(
507                            long ldapServerId, long companyId, LdapContext ldapContext,
508                            String fullDistinguishedName)
509                    throws Exception {
510    
511                    Properties userMappings = LDAPSettingsUtil.getUserMappings(
512                            ldapServerId, companyId);
513                    Properties userExpandoMappings =
514                            LDAPSettingsUtil.getUserExpandoMappings(ldapServerId, companyId);
515    
516                    PropertiesUtil.merge(userMappings, userExpandoMappings);
517    
518                    Properties contactMappings = LDAPSettingsUtil.getContactMappings(
519                            ldapServerId, companyId);
520                    Properties contactExpandoMappings =
521                            LDAPSettingsUtil.getContactExpandoMappings(ldapServerId, companyId);
522    
523                    PropertiesUtil.merge(contactMappings, contactExpandoMappings);
524    
525                    PropertiesUtil.merge(userMappings, contactMappings);
526    
527                    String[] mappedUserAttributeIds = ArrayUtil.toStringArray(
528                            userMappings.values().toArray(new Object[userMappings.size()]));
529    
530                    return _getAttributes(
531                            ldapContext, fullDistinguishedName, mappedUserAttributeIds);
532            }
533    
534            public static byte[] getUsers(
535                            long companyId, LdapContext ldapContext, byte[] cookie,
536                            int maxResults, String baseDN, String userFilter,
537                            List<SearchResult> searchResults)
538                    throws Exception {
539    
540                    return searchLDAP(
541                            companyId, ldapContext, cookie, maxResults, baseDN, userFilter,
542                            null, searchResults);
543            }
544    
545            public static byte[] getUsers(
546                            long companyId, LdapContext ldapContext, byte[] cookie,
547                            int maxResults, String baseDN, String userFilter,
548                            String[] attributeIds, List<SearchResult> searchResults)
549                    throws Exception {
550    
551                    return searchLDAP(
552                            companyId, ldapContext, cookie, maxResults, baseDN, userFilter,
553                            attributeIds, searchResults);
554            }
555    
556            public static byte[] getUsers(
557                            long ldapServerId, long companyId, LdapContext ldapContext,
558                            byte[] cookie, int maxResults, List<SearchResult> searchResults)
559                    throws Exception {
560    
561                    String postfix = LDAPSettingsUtil.getPropertyPostfix(ldapServerId);
562    
563                    String baseDN = PrefsPropsUtil.getString(
564                            companyId, PropsKeys.LDAP_BASE_DN + postfix);
565                    String userFilter = PrefsPropsUtil.getString(
566                            companyId, PropsKeys.LDAP_IMPORT_USER_SEARCH_FILTER + postfix);
567    
568                    return getUsers(
569                            companyId, ldapContext, cookie, maxResults, baseDN, userFilter,
570                            searchResults);
571            }
572    
573            public static byte[] getUsers(
574                            long ldapServerId, long companyId, LdapContext ldapContext,
575                            byte[] cookie, int maxResults, String[] attributeIds,
576                            List<SearchResult> searchResults)
577                    throws Exception {
578    
579                    String postfix = LDAPSettingsUtil.getPropertyPostfix(ldapServerId);
580    
581                    String baseDN = PrefsPropsUtil.getString(
582                            companyId, PropsKeys.LDAP_BASE_DN + postfix);
583                    String userFilter = PrefsPropsUtil.getString(
584                            companyId, PropsKeys.LDAP_IMPORT_USER_SEARCH_FILTER + postfix);
585    
586                    return getUsers(
587                            companyId, ldapContext, cookie, maxResults, baseDN, userFilter,
588                            attributeIds, searchResults);
589            }
590    
591            public static String getUsersDN(long ldapServerId, long companyId)
592                    throws Exception {
593    
594                    String postfix = LDAPSettingsUtil.getPropertyPostfix(ldapServerId);
595    
596                    return PrefsPropsUtil.getString(
597                            companyId, PropsKeys.LDAP_USERS_DN + postfix);
598            }
599    
600            public static boolean hasUser(
601                            long ldapServerId, long companyId, String screenName,
602                            String emailAddress)
603                    throws Exception {
604    
605                    if (getUser(
606                                    ldapServerId, companyId, screenName, emailAddress) != null) {
607    
608                            return true;
609                    }
610                    else {
611                            return false;
612                    }
613            }
614    
615            public static boolean isGroupMember(
616                            long ldapServerId, long companyId, String groupDN, String userDN)
617                    throws Exception {
618    
619                    LdapContext ldapContext = getContext(ldapServerId, companyId);
620    
621                    NamingEnumeration<SearchResult> enu = null;
622    
623                    try {
624                            if (ldapContext == null) {
625                                    return false;
626                            }
627    
628                            Properties groupMappings = LDAPSettingsUtil.getGroupMappings(
629                                    ldapServerId, companyId);
630    
631                            StringBundler filter = new StringBundler(5);
632    
633                            filter.append(StringPool.OPEN_PARENTHESIS);
634                            filter.append(groupMappings.getProperty(GroupConverterKeys.USER));
635                            filter.append(StringPool.EQUAL);
636                            filter.append(userDN);
637                            filter.append(StringPool.CLOSE_PARENTHESIS);
638    
639                            SearchControls searchControls = new SearchControls(
640                                    SearchControls.SUBTREE_SCOPE, 1, 0, null, false, false);
641    
642                            enu = ldapContext.search(
643                                    groupDN, filter.toString(), searchControls);
644    
645                            if (enu.hasMoreElements()) {
646                                    return true;
647                            }
648                    }
649                    catch (NameNotFoundException nnfe) {
650                            if (_log.isWarnEnabled()) {
651                                    _log.warn(
652                                            "Unable to determine if user DN " + userDN +
653                                                    " is a member of group DN " + groupDN,
654                                            nnfe);
655                            }
656                    }
657                    finally {
658                            if (enu != null) {
659                                    enu.close();
660                            }
661    
662                            if (ldapContext != null) {
663                                    ldapContext.close();
664                            }
665                    }
666    
667                    return false;
668            }
669    
670            public static boolean isUserGroupMember(
671                            long ldapServerId, long companyId, String groupDN, String userDN)
672                    throws Exception {
673    
674                    LdapContext ldapContext = getContext(ldapServerId, companyId);
675    
676                    NamingEnumeration<SearchResult> enu = null;
677    
678                    try {
679                            if (ldapContext == null) {
680                                    return false;
681                            }
682    
683                            Properties userMappings = LDAPSettingsUtil.getUserMappings(
684                                    ldapServerId, companyId);
685    
686                            StringBundler filter = new StringBundler(5);
687    
688                            filter.append(StringPool.OPEN_PARENTHESIS);
689                            filter.append(userMappings.getProperty(UserConverterKeys.GROUP));
690                            filter.append(StringPool.EQUAL);
691                            filter.append(groupDN);
692                            filter.append(StringPool.CLOSE_PARENTHESIS);
693    
694                            SearchControls searchControls = new SearchControls(
695                                    SearchControls.SUBTREE_SCOPE, 1, 0, null, false, false);
696    
697                            enu = ldapContext.search(userDN, filter.toString(), searchControls);
698    
699                            if (enu.hasMoreElements()) {
700                                    return true;
701                            }
702                    }
703                    catch (NameNotFoundException nnfe) {
704                            if (_log.isWarnEnabled()) {
705                                    _log.warn(
706                                            "Unable to determine if group DN " + groupDN +
707                                                    " is a member of user DN " + userDN,
708                                            nnfe);
709                            }
710                    }
711                    finally {
712                            if (enu != null) {
713                                    enu.close();
714                            }
715    
716                            if (ldapContext != null) {
717                                    ldapContext.close();
718                            }
719                    }
720    
721                    return false;
722            }
723    
724            public static byte[] searchLDAP(
725                            long companyId, LdapContext ldapContext, byte[] cookie,
726                            int maxResults, String baseDN, String filter, String[] attributeIds,
727                            List<SearchResult> searchResults)
728                    throws Exception {
729    
730                    SearchControls searchControls = new SearchControls(
731                            SearchControls.SUBTREE_SCOPE, maxResults, 0, attributeIds, false,
732                            false);
733    
734                    NamingEnumeration<SearchResult> enu = null;
735    
736                    try {
737                            if (cookie != null) {
738                                    if (cookie.length == 0) {
739                                            ldapContext.setRequestControls(
740                                                    new Control[] {
741                                                            new PagedResultsControl(
742                                                                    PropsValues.LDAP_PAGE_SIZE, Control.CRITICAL)
743                                                    });
744                                    }
745                                    else {
746                                            ldapContext.setRequestControls(
747                                                    new Control[] {
748                                                            new PagedResultsControl(
749                                                                    PropsValues.LDAP_PAGE_SIZE, cookie,
750                                                                    Control.CRITICAL)
751                                                    });
752                                    }
753    
754                                    enu = ldapContext.search(baseDN, filter, searchControls);
755    
756                                    while (enu.hasMoreElements()) {
757                                            searchResults.add(enu.nextElement());
758                                    }
759    
760                                    return _getCookie(ldapContext.getResponseControls());
761                            }
762                    }
763                    catch (OperationNotSupportedException onse) {
764                            if (enu != null) {
765                                    enu.close();
766                            }
767    
768                            ldapContext.setRequestControls(null);
769    
770                            enu = ldapContext.search(baseDN, filter, searchControls);
771    
772                            while (enu.hasMoreElements()) {
773                                    searchResults.add(enu.nextElement());
774                            }
775                    }
776                    finally {
777                            if (enu != null) {
778                                    enu.close();
779                            }
780    
781                            ldapContext.setRequestControls(null);
782                    }
783    
784                    return null;
785            }
786    
787            private static Attributes _getAttributes(
788                            LdapContext ldapContext, String fullDistinguishedName,
789                            String[] attributeIds)
790                    throws Exception {
791    
792                    Name fullDN = new CompositeName().add(fullDistinguishedName);
793    
794                    Attributes attributes = null;
795    
796                    String[] auditAttributeIds = {
797                            "creatorsName", "createTimestamp", "modifiersName",
798                            "modifyTimestamp"
799                    };
800    
801                    if (attributeIds == null) {
802    
803                            // Get complete listing of LDAP attributes (slow)
804    
805                            attributes = ldapContext.getAttributes(fullDN);
806    
807                            NamingEnumeration<? extends Attribute> enu = null;
808    
809                            try {
810                                    enu = ldapContext.getAttributes(
811                                            fullDN, auditAttributeIds).getAll();
812    
813                                    while (enu.hasMoreElements()) {
814                                            attributes.put(enu.nextElement());
815                                    }
816                            }
817                            finally {
818                                    if (enu != null) {
819                                            enu.close();
820                                    }
821                            }
822                    }
823                    else {
824    
825                            // Get specified LDAP attributes
826    
827                            int attributeCount = attributeIds.length + auditAttributeIds.length;
828    
829                            String[] allAttributeIds = new String[attributeCount];
830    
831                            System.arraycopy(
832                                    attributeIds, 0, allAttributeIds, 0, attributeIds.length);
833                            System.arraycopy(
834                                    auditAttributeIds, 0, allAttributeIds, attributeIds.length,
835                                    auditAttributeIds.length);
836    
837                            attributes = ldapContext.getAttributes(fullDN, allAttributeIds);
838                    }
839    
840                    return attributes;
841            }
842    
843            private static byte[] _getCookie(Control[] controls) {
844                    if (controls == null) {
845                            return null;
846                    }
847    
848                    for (Control control : controls) {
849                            if (control instanceof PagedResultsResponseControl) {
850                                    PagedResultsResponseControl pagedResultsResponseControl =
851                                            (PagedResultsResponseControl)control;
852    
853                                    return pagedResultsResponseControl.getCookie();
854                            }
855                    }
856    
857                    return null;
858            }
859    
860            private static String _getNextRange(String attributeId) {
861                    String originalAttributeId = null;
862                    int start = 0;
863                    int end = 0;
864    
865                    int x = attributeId.indexOf(CharPool.SEMICOLON);
866    
867                    if (x < 0) {
868                            originalAttributeId = attributeId;
869                            end = PropsValues.LDAP_RANGE_SIZE - 1;
870                    }
871                    else {
872                            int y = attributeId.indexOf(CharPool.EQUAL, x);
873                            int z = attributeId.indexOf(CharPool.DASH, y);
874    
875                            originalAttributeId = attributeId.substring(0, x);
876                            start = GetterUtil.getInteger(attributeId.substring(y + 1, z));
877                            end = GetterUtil.getInteger(attributeId.substring(z + 1));
878    
879                            start += PropsValues.LDAP_RANGE_SIZE;
880                            end += PropsValues.LDAP_RANGE_SIZE;
881                    }
882    
883                    StringBundler sb = new StringBundler(6);
884    
885                    sb.append(originalAttributeId);
886                    sb.append(StringPool.SEMICOLON);
887                    sb.append("range=");
888                    sb.append(start);
889                    sb.append(StringPool.DASH);
890                    sb.append(end);
891    
892                    return sb.toString();
893            }
894    
895            private static Log _log = LogFactoryUtil.getLog(PortalLDAPUtil.class);
896    
897    }