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