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