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