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