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