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