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