001    /**
002     * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
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.PropsValues;
032    
033    import java.util.ArrayList;
034    import java.util.List;
035    import java.util.Properties;
036    
037    import javax.naming.Binding;
038    import javax.naming.CompositeName;
039    import javax.naming.Context;
040    import javax.naming.Name;
041    import javax.naming.NameNotFoundException;
042    import javax.naming.NamingEnumeration;
043    import javax.naming.OperationNotSupportedException;
044    import javax.naming.directory.Attribute;
045    import javax.naming.directory.Attributes;
046    import javax.naming.directory.SearchControls;
047    import javax.naming.directory.SearchResult;
048    import javax.naming.ldap.Control;
049    import javax.naming.ldap.InitialLdapContext;
050    import javax.naming.ldap.LdapContext;
051    import javax.naming.ldap.PagedResultsControl;
052    import javax.naming.ldap.PagedResultsResponseControl;
053    
054    /**
055     * @author Michael Young
056     * @author Brian Wing Shun Chan
057     * @author Jerry Niu
058     * @author Scott Lee
059     * @author Hervé Ménage
060     * @author Samuel Kong
061     * @author Ryan Park
062     * @author Wesley Gong
063     * @author Marcellus Tavares
064     * @author Hugo Huijser
065     */
066    public class PortalLDAPUtil {
067    
068            public static LdapContext getContext(long ldapServerId, long companyId)
069                    throws Exception {
070    
071                    String postfix = LDAPSettingsUtil.getPropertyPostfix(ldapServerId);
072    
073                    String baseProviderURL = PrefsPropsUtil.getString(
074                            companyId, PropsKeys.LDAP_BASE_PROVIDER_URL + postfix);
075                    String pricipal = PrefsPropsUtil.getString(
076                            companyId, PropsKeys.LDAP_SECURITY_PRINCIPAL + postfix);
077                    String credentials = PrefsPropsUtil.getString(
078                            companyId, PropsKeys.LDAP_SECURITY_CREDENTIALS + postfix);
079    
080                    return getContext(companyId, baseProviderURL, pricipal, credentials);
081            }
082    
083            public static LdapContext getContext(
084                            long companyId, String providerURL, String principal,
085                            String credentials)
086                    throws Exception {
087    
088                    Properties env = new Properties();
089    
090                    env.put(
091                            Context.INITIAL_CONTEXT_FACTORY,
092                            PrefsPropsUtil.getString(
093                                    companyId, PropsKeys.LDAP_FACTORY_INITIAL));
094                    env.put(Context.PROVIDER_URL, providerURL);
095                    env.put(Context.SECURITY_PRINCIPAL, principal);
096                    env.put(Context.SECURITY_CREDENTIALS, credentials);
097                    env.put(
098                            Context.REFERRAL,
099                            PrefsPropsUtil.getString(companyId, PropsKeys.LDAP_REFERRAL));
100    
101                    // Enable pooling
102    
103                    env.put("com.sun.jndi.ldap.connect.pool", "true");
104                    env.put("com.sun.jndi.ldap.connect.pool.maxsize","50");
105                    env.put("com.sun.jndi.ldap.connect.pool.timeout", "10000");
106    
107                    LogUtil.debug(_log, env);
108    
109                    LdapContext ldapContext = null;
110    
111                    try {
112                            ldapContext = new InitialLdapContext(env, 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(
508                                    ldapServerId, companyId);
509    
510                    PropertiesUtil.merge(userMappings, userExpandoMappings);
511    
512                    Properties contactMappings = LDAPSettingsUtil.getContactMappings(
513                            ldapServerId, companyId);
514                    Properties contactExpandoMappings =
515                            LDAPSettingsUtil.getContactExpandoMappings(ldapServerId, companyId);
516    
517                    PropertiesUtil.merge(contactMappings, contactExpandoMappings);
518    
519                    PropertiesUtil.merge(userMappings, contactMappings);
520    
521                    String[] mappedUserAttributeIds = ArrayUtil.toStringArray(
522                            userMappings.values().toArray(new Object[userMappings.size()]));
523    
524                    return _getAttributes(
525                            ldapContext, fullDistinguishedName, mappedUserAttributeIds);
526            }
527    
528            public static byte[] getUsers(
529                            long companyId, LdapContext ldapContext, byte[] cookie,
530                            int maxResults, String baseDN, String userFilter,
531                            List<SearchResult> searchResults)
532                    throws Exception {
533    
534                    return searchLDAP(
535                            companyId, ldapContext, cookie, maxResults, baseDN, userFilter,
536                            null, searchResults);
537            }
538    
539            public static byte[] getUsers(
540                            long companyId, LdapContext ldapContext, byte[] cookie,
541                            int maxResults, String baseDN, String userFilter,
542                            String[] attributeIds, List<SearchResult> searchResults)
543                    throws Exception {
544    
545                    return searchLDAP(
546                            companyId, ldapContext, cookie, maxResults, baseDN, userFilter,
547                            attributeIds, searchResults);
548            }
549    
550            public static byte[] getUsers(
551                            long ldapServerId, long companyId, LdapContext ldapContext,
552                            byte[] cookie, int maxResults, List<SearchResult> searchResults)
553                    throws Exception {
554    
555                    String postfix = LDAPSettingsUtil.getPropertyPostfix(ldapServerId);
556    
557                    String baseDN = PrefsPropsUtil.getString(
558                            companyId, PropsKeys.LDAP_BASE_DN + postfix);
559                    String userFilter = PrefsPropsUtil.getString(
560                            companyId, PropsKeys.LDAP_IMPORT_USER_SEARCH_FILTER + postfix);
561    
562                    return getUsers(
563                            companyId, ldapContext, cookie, maxResults, baseDN, userFilter,
564                            searchResults);
565            }
566    
567            public static byte[] getUsers(
568                            long ldapServerId, long companyId, LdapContext ldapContext,
569                            byte[] cookie, int maxResults, String[] attributeIds,
570                            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                            attributeIds, searchResults);
583            }
584    
585            public static String getUsersDN(long ldapServerId, long companyId)
586                    throws Exception {
587    
588                    String postfix = LDAPSettingsUtil.getPropertyPostfix(ldapServerId);
589    
590                    return PrefsPropsUtil.getString(
591                            companyId, PropsKeys.LDAP_USERS_DN + postfix);
592            }
593    
594            public static boolean hasUser(
595                            long ldapServerId, long companyId, String screenName,
596                            String emailAddress)
597                    throws Exception {
598    
599                    if (getUser(
600                                    ldapServerId, companyId, screenName, emailAddress) != null) {
601    
602                            return true;
603                    }
604                    else {
605                            return false;
606                    }
607            }
608    
609            public static boolean isGroupMember(
610                            long ldapServerId, long companyId, String groupDN, String userDN)
611                    throws Exception {
612    
613                    LdapContext ldapContext = getContext(ldapServerId, companyId);
614    
615                    try {
616                            if (ldapContext == null) {
617                                    return false;
618                            }
619    
620                            Properties groupMappings = LDAPSettingsUtil.getGroupMappings(
621                                    ldapServerId, companyId);
622    
623                            StringBundler filter = new StringBundler(5);
624    
625                            filter.append(StringPool.OPEN_PARENTHESIS);
626                            filter.append(groupMappings.getProperty(GroupConverterKeys.USER));
627                            filter.append(StringPool.EQUAL);
628                            filter.append(userDN);
629                            filter.append(StringPool.CLOSE_PARENTHESIS);
630    
631                            SearchControls searchControls = new SearchControls(
632                                    SearchControls.SUBTREE_SCOPE, 1, 0, null, false, false);
633    
634                            NamingEnumeration<SearchResult> enu = ldapContext.search(
635                                    groupDN, filter.toString(), searchControls);
636    
637                            if (enu.hasMoreElements()) {
638                                    return true;
639                            }
640                    }
641                    catch (NameNotFoundException nnfe) {
642                            if (_log.isWarnEnabled()) {
643                                    _log.warn(
644                                            "Unable to determine if user DN " + userDN +
645                                                    " is a member of group DN " + groupDN,
646                                            nnfe);
647                            }
648                    }
649                    finally {
650                            if (ldapContext != null) {
651                                    ldapContext.close();
652                            }
653                    }
654    
655                    return false;
656            }
657    
658            public static boolean isUserGroupMember(
659                            long ldapServerId, long companyId, String groupDN, String userDN)
660                    throws Exception {
661    
662                    LdapContext ldapContext = getContext(ldapServerId, companyId);
663    
664                    try {
665                            if (ldapContext == null) {
666                                    return false;
667                            }
668    
669                            Properties userMappings = LDAPSettingsUtil.getUserMappings(
670                                    ldapServerId, companyId);
671    
672                            StringBundler filter = new StringBundler(5);
673    
674                            filter.append(StringPool.OPEN_PARENTHESIS);
675                            filter.append(userMappings.getProperty(UserConverterKeys.GROUP));
676                            filter.append(StringPool.EQUAL);
677                            filter.append(groupDN);
678                            filter.append(StringPool.CLOSE_PARENTHESIS);
679    
680                            SearchControls searchControls = new SearchControls(
681                                    SearchControls.SUBTREE_SCOPE, 1, 0, null, false, false);
682    
683                            NamingEnumeration<SearchResult> enu = ldapContext.search(
684                                    userDN, filter.toString(), searchControls);
685    
686                            if (enu.hasMoreElements()) {
687                                    return true;
688                            }
689                    }
690                    catch (NameNotFoundException nnfe) {
691                            if (_log.isWarnEnabled()) {
692                                    _log.warn(
693                                            "Unable to determine if group DN " + groupDN +
694                                                    " is a member of user DN " + userDN,
695                                            nnfe);
696                            }
697                    }
698                    finally {
699                            if (ldapContext != null) {
700                                    ldapContext.close();
701                            }
702                    }
703    
704                    return false;
705            }
706    
707            public static byte[] searchLDAP(
708                            long companyId, LdapContext ldapContext, byte[] cookie,
709                            int maxResults, String baseDN, String filter,
710                            String[] attributeIds, List<SearchResult> searchResults)
711                    throws Exception {
712    
713                    SearchControls searchControls = new SearchControls(
714                            SearchControls.SUBTREE_SCOPE, maxResults, 0, attributeIds, false,
715                            false);
716    
717                    try {
718                            if (cookie != null) {
719                                    if (cookie.length == 0) {
720                                            ldapContext.setRequestControls(
721                                                    new Control[] {
722                                                            new PagedResultsControl(
723                                                                    PropsValues.LDAP_PAGE_SIZE, Control.CRITICAL)
724                                                    });
725                                    }
726                                    else {
727                                            ldapContext.setRequestControls(
728                                                    new Control[] {
729                                                            new PagedResultsControl(
730                                                                    PropsValues.LDAP_PAGE_SIZE, cookie,
731                                                                    Control.CRITICAL)
732                                                    });
733                                    }
734    
735                                    NamingEnumeration<SearchResult> enu = ldapContext.search(
736                                            baseDN, filter, searchControls);
737    
738                                    while (enu.hasMoreElements()) {
739                                            searchResults.add(enu.nextElement());
740                                    }
741    
742                                    enu.close();
743    
744                                    return _getCookie(ldapContext.getResponseControls());
745                            }
746                    }
747                    catch (OperationNotSupportedException onse) {
748                            ldapContext.setRequestControls(null);
749    
750                            NamingEnumeration<SearchResult> enu = ldapContext.search(
751                                    baseDN, filter, searchControls);
752    
753                            while (enu.hasMoreElements()) {
754                                    searchResults.add(enu.nextElement());
755                            }
756    
757                            enu.close();
758                    }
759                    finally {
760                            ldapContext.setRequestControls(null);
761                    }
762    
763                    return null;
764            }
765    
766            private static Attributes _getAttributes(
767                            LdapContext ldapContext, String fullDistinguishedName,
768                            String[] attributeIds)
769                    throws Exception {
770    
771                    Name fullDN = new CompositeName().add(fullDistinguishedName);
772    
773                    Attributes attributes = null;
774    
775                    String[] auditAttributeIds = {
776                            "creatorsName", "createTimestamp", "modifiersName",
777                            "modifyTimestamp"
778                    };
779    
780                    if (attributeIds == null) {
781    
782                            // Get complete listing of LDAP attributes (slow)
783    
784                            attributes = ldapContext.getAttributes(fullDN);
785    
786                            NamingEnumeration<? extends Attribute> enu =
787                                    ldapContext.getAttributes(fullDN, auditAttributeIds).getAll();
788    
789                            while (enu.hasMoreElements()) {
790                                    attributes.put(enu.nextElement());
791                            }
792    
793                            enu.close();
794                    }
795                    else {
796    
797                            // Get specified LDAP attributes
798    
799                            int attributeCount = attributeIds.length + auditAttributeIds.length;
800    
801                            String[] allAttributeIds = new String[attributeCount];
802    
803                            System.arraycopy(
804                                    attributeIds, 0, allAttributeIds, 0, attributeIds.length);
805                            System.arraycopy(
806                                    auditAttributeIds, 0, allAttributeIds, attributeIds.length,
807                                    auditAttributeIds.length);
808    
809                            attributes = ldapContext.getAttributes(fullDN, allAttributeIds);
810                    }
811    
812                    return attributes;
813            }
814    
815            private static byte[] _getCookie(Control[] controls) {
816                    if (controls == null) {
817                            return null;
818                    }
819    
820                    for (Control control : controls) {
821                            if (control instanceof PagedResultsResponseControl) {
822                                    PagedResultsResponseControl pagedResultsResponseControl =
823                                            (PagedResultsResponseControl)control;
824    
825                                    return pagedResultsResponseControl.getCookie();
826                            }
827                    }
828    
829                    return null;
830            }
831    
832            private static String _getNextRange(String attributeId) {
833                    String originalAttributeId = null;
834                    int start = 0;
835                    int end = 0;
836    
837                    int x = attributeId.indexOf(CharPool.SEMICOLON);
838    
839                    if (x < 0) {
840                            originalAttributeId = attributeId;
841                            end = PropsValues.LDAP_RANGE_SIZE - 1;
842                    }
843                    else {
844                            int y = attributeId.indexOf(CharPool.EQUAL, x);
845                            int z = attributeId.indexOf(CharPool.DASH, y);
846    
847                            originalAttributeId = attributeId.substring(0, x);
848                            start = GetterUtil.getInteger(attributeId.substring(y + 1, z));
849                            end = GetterUtil.getInteger(attributeId.substring(z + 1));
850    
851                            start += PropsValues.LDAP_RANGE_SIZE;
852                            end += PropsValues.LDAP_RANGE_SIZE;
853                    }
854    
855                    StringBundler sb = new StringBundler(6);
856    
857                    sb.append(originalAttributeId);
858                    sb.append(StringPool.SEMICOLON);
859                    sb.append("range=");
860                    sb.append(start);
861                    sb.append(StringPool.DASH);
862                    sb.append(end);
863    
864                    return sb.toString();
865            }
866    
867            private static Log _log = LogFactoryUtil.getLog(PortalLDAPUtil.class);
868    
869    }