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