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