1
14
15 package com.liferay.portal.security.ldap;
16
17 import com.liferay.portal.SystemException;
18 import com.liferay.portal.kernel.log.Log;
19 import com.liferay.portal.kernel.log.LogFactoryUtil;
20 import com.liferay.portal.kernel.log.LogUtil;
21 import com.liferay.portal.kernel.util.CharPool;
22 import com.liferay.portal.kernel.util.GetterUtil;
23 import com.liferay.portal.kernel.util.PropsKeys;
24 import com.liferay.portal.kernel.util.StringBundler;
25 import com.liferay.portal.kernel.util.StringPool;
26 import com.liferay.portal.kernel.util.StringUtil;
27 import com.liferay.portal.kernel.util.Validator;
28 import com.liferay.portal.model.Contact;
29 import com.liferay.portal.model.User;
30 import com.liferay.portal.model.UserGroup;
31 import com.liferay.portal.security.auth.AuthSettingsUtil;
32 import com.liferay.portal.util.PrefsPropsUtil;
33 import com.liferay.portal.util.PropsValues;
34
35 import java.util.ArrayList;
36 import java.util.List;
37 import java.util.Properties;
38
39 import javax.naming.Binding;
40 import javax.naming.CompositeName;
41 import javax.naming.Context;
42 import javax.naming.Name;
43 import javax.naming.NamingEnumeration;
44 import javax.naming.OperationNotSupportedException;
45 import javax.naming.directory.Attribute;
46 import javax.naming.directory.Attributes;
47 import javax.naming.directory.SearchControls;
48 import javax.naming.directory.SearchResult;
49 import javax.naming.ldap.Control;
50 import javax.naming.ldap.InitialLdapContext;
51 import javax.naming.ldap.LdapContext;
52 import javax.naming.ldap.PagedResultsControl;
53 import javax.naming.ldap.PagedResultsResponseControl;
54
55
67 public class PortalLDAPUtil {
68
69
72 public static final String IMPORT_BY_GROUP =
73 PortalLDAPImporter.IMPORT_BY_GROUP;
74
75
78 public static final String IMPORT_BY_USER =
79 PortalLDAPImporter.IMPORT_BY_USER;
80
81
84 public static void exportToLDAP(Contact contact) throws Exception {
85 PortalLDAPExporter.exportToLDAP(contact);
86 }
87
88
91 public static void exportToLDAP(User user) throws Exception {
92 PortalLDAPExporter.exportToLDAP(user);
93 }
94
95
99 public static String getAuthSearchFilter(
100 long ldapServerId, long companyId, String emailAddress,
101 String screenName, String userId)
102 throws SystemException {
103
104 return LDAPSettingsUtil.getAuthSearchFilter(
105 ldapServerId, companyId, emailAddress, screenName, userId);
106 }
107
108 public static LdapContext getContext(long ldapServerId, long companyId)
109 throws Exception {
110
111 String postfix = LDAPSettingsUtil.getPropertyPostfix(ldapServerId);
112
113 String baseProviderURL = PrefsPropsUtil.getString(
114 companyId, PropsKeys.LDAP_BASE_PROVIDER_URL + postfix);
115 String pricipal = PrefsPropsUtil.getString(
116 companyId, PropsKeys.LDAP_SECURITY_PRINCIPAL + postfix);
117 String credentials = PrefsPropsUtil.getString(
118 companyId, PropsKeys.LDAP_SECURITY_CREDENTIALS + postfix);
119
120 return getContext(companyId, baseProviderURL, pricipal, credentials);
121 }
122
123 public static LdapContext getContext(
124 long companyId, String providerURL, String principal,
125 String credentials)
126 throws Exception {
127
128 Properties env = new Properties();
129
130 env.put(
131 Context.INITIAL_CONTEXT_FACTORY,
132 PrefsPropsUtil.getString(
133 companyId, PropsKeys.LDAP_FACTORY_INITIAL));
134 env.put(Context.PROVIDER_URL, providerURL);
135 env.put(Context.SECURITY_PRINCIPAL, principal);
136 env.put(Context.SECURITY_CREDENTIALS, credentials);
137 env.put(
138 Context.REFERRAL,
139 PrefsPropsUtil.getString(companyId, PropsKeys.LDAP_REFERRAL));
140
141
143 env.put("com.sun.jndi.ldap.connect.pool", "true");
144 env.put("com.sun.jndi.ldap.connect.pool.maxsize","50");
145 env.put("com.sun.jndi.ldap.connect.pool.timeout", "10000");
146
147 LogUtil.debug(_log, env);
148
149 LdapContext ldapContext = null;
150
151 try {
152 ldapContext = new InitialLdapContext(env, null);
153 }
154 catch (Exception e) {
155 if (_log.isWarnEnabled()) {
156 _log.warn("Failed to bind to the LDAP server");
157 }
158
159 if (_log.isDebugEnabled()) {
160 _log.debug(e, e);
161 }
162 }
163
164 return ldapContext;
165 }
166
167 public static Attributes getGroupAttributes(
168 long ldapServerId, long companyId, LdapContext ldapContext,
169 String fullDistinguishedName)
170 throws Exception {
171
172 return getGroupAttributes(ldapServerId, companyId, ldapContext,
173 fullDistinguishedName, false);
174 }
175
176 public static Attributes getGroupAttributes(
177 long ldapServerId, long companyId, LdapContext ldapContext,
178 String fullDistinguishedName, boolean includeReferenceAttributes)
179 throws Exception {
180
181 Properties groupMappings = LDAPSettingsUtil.getGroupMappings(
182 ldapServerId, companyId);
183
184 List<String> mappedGroupAttributeIds = new ArrayList<String>();
185
186 mappedGroupAttributeIds.add(groupMappings.getProperty("groupName"));
187 mappedGroupAttributeIds.add(groupMappings.getProperty("description"));
188
189 if (includeReferenceAttributes) {
190 mappedGroupAttributeIds.add(groupMappings.getProperty("user"));
191 }
192
193 return _getAttributes(
194 ldapContext, fullDistinguishedName,
195 mappedGroupAttributeIds.toArray(new String[0]));
196 }
197
198
201 public static Properties getGroupMappings(long ldapServerId, long companyId)
202 throws Exception {
203
204 return LDAPSettingsUtil.getGroupMappings(ldapServerId, companyId);
205 }
206
207 public static byte[] getGroups(
208 long companyId, LdapContext ldapContext, byte[] cookie,
209 int maxResults, String baseDN, String groupFilter,
210 List<SearchResult> searchResults)
211 throws Exception {
212
213 return searchLDAP(
214 companyId, ldapContext, cookie, maxResults, baseDN, groupFilter,
215 null, searchResults);
216 }
217
218 public static byte[] getGroups(
219 long companyId, LdapContext ldapContext, byte[] cookie,
220 int maxResults, String baseDN, String groupFilter,
221 String[] attributeIds, List<SearchResult> searchResults)
222 throws Exception {
223
224 return searchLDAP(
225 companyId, ldapContext, cookie, maxResults, baseDN, groupFilter,
226 attributeIds, searchResults);
227 }
228
229 public static byte[] getGroups(
230 long ldapServerId, long companyId, LdapContext ldapContext,
231 byte[] cookie, int maxResults, List<SearchResult> searchResults)
232 throws Exception {
233
234 String postfix = LDAPSettingsUtil.getPropertyPostfix(ldapServerId);
235
236 String baseDN = PrefsPropsUtil.getString(
237 companyId, PropsKeys.LDAP_BASE_DN + postfix);
238 String groupFilter = PrefsPropsUtil.getString(
239 companyId, PropsKeys.LDAP_IMPORT_GROUP_SEARCH_FILTER + postfix);
240
241 return getGroups(
242 companyId, ldapContext, cookie, maxResults, baseDN, groupFilter,
243 searchResults);
244 }
245
246 public static byte[] getGroups(
247 long ldapServerId, long companyId, LdapContext ldapContext,
248 byte[] cookie, int maxResults, String[] attributeIds,
249 List<SearchResult> searchResults)
250 throws Exception {
251
252 String postfix = LDAPSettingsUtil.getPropertyPostfix(ldapServerId);
253
254 String baseDN = PrefsPropsUtil.getString(
255 companyId, PropsKeys.LDAP_BASE_DN + postfix);
256 String groupFilter = PrefsPropsUtil.getString(
257 companyId, PropsKeys.LDAP_IMPORT_GROUP_SEARCH_FILTER + postfix);
258
259 return getGroups(
260 companyId, ldapContext, cookie, maxResults, baseDN, groupFilter,
261 attributeIds, searchResults);
262 }
263
264 public static long getLdapServerId(long companyId, String screenName)
265 throws Exception {
266
267 long[] ldapServerIds = StringUtil.split(
268 PrefsPropsUtil.getString(companyId, "ldap.server.ids"), 0L);
269
270 for (long ldapServerId : ldapServerIds) {
271 if (hasUser(ldapServerId, companyId, screenName)) {
272 return ldapServerId;
273 }
274 }
275
276 if (ldapServerIds.length > 0) {
277 return ldapServerIds[0];
278 }
279
280 return 0;
281 }
282
283 public static Attribute getMultivaluedAttribute(
284 long companyId, LdapContext ldapContext, String baseDN,
285 String filter, Attribute attribute)
286 throws Exception {
287
288 if (attribute.size() > 0) {
289 return attribute;
290 }
291
292 String[] attributeIds = {_getNextRange(attribute.getID())};
293
294 while (true) {
295 List<SearchResult> searchResults = new ArrayList<SearchResult>();
296
297 searchLDAP(
298 companyId, ldapContext, new byte[0], 0, baseDN, filter,
299 attributeIds, searchResults);
300
301 if (searchResults.size() != 1) {
302 break;
303 }
304
305 SearchResult searchResult = searchResults.get(0);
306
307 Attributes attributes = searchResult.getAttributes();
308
309 if (attributes.size() != 1) {
310 break;
311 }
312
313 NamingEnumeration<? extends Attribute> enu = attributes.getAll();
314
315 if (!enu.hasMoreElements()) {
316 break;
317 }
318
319 Attribute curAttribute = enu.nextElement();
320
321 for (int i = 0; i < curAttribute.size(); i++) {
322 attribute.add(curAttribute.get(i));
323 }
324
325 if (StringUtil.endsWith(curAttribute.getID(), StringPool.STAR) ||
326 (curAttribute.size() < PropsValues.LDAP_RANGE_SIZE)) {
327
328 break;
329 }
330
331 attributeIds[0] = _getNextRange(attributeIds[0]);
332 }
333
334 return attribute;
335 }
336
337 public static String getNameInNamespace(
338 long ldapServerId, long companyId, Binding binding)
339 throws Exception {
340
341 String postfix = LDAPSettingsUtil.getPropertyPostfix(ldapServerId);
342
343 String baseDN = PrefsPropsUtil.getString(
344 companyId, PropsKeys.LDAP_BASE_DN + postfix);
345
346 String name = binding.getName();
347
348 if (name.startsWith(StringPool.QUOTE) &&
349 name.endsWith(StringPool.QUOTE)) {
350
351 name = name.substring(1, name.length() - 1);
352 }
353
354 if (Validator.isNull(baseDN)) {
355 return name.toString();
356 }
357 else {
358 return name.concat(StringPool.COMMA).concat(baseDN);
359 }
360 }
361
362 public static Binding getUser(
363 long ldapServerId, long companyId, String screenName)
364 throws Exception {
365
366 String postfix = LDAPSettingsUtil.getPropertyPostfix(ldapServerId);
367
368 LdapContext ldapContext = getContext(ldapServerId, companyId);
369
370 NamingEnumeration<SearchResult> enu = null;
371
372 try {
373 if (ldapContext == null) {
374 return null;
375 }
376
377 String baseDN = PrefsPropsUtil.getString(
378 companyId, PropsKeys.LDAP_BASE_DN + postfix);
379
380 Properties userMappings = LDAPSettingsUtil.getUserMappings(
381 ldapServerId, companyId);
382
383 StringBundler filter = new StringBundler(5);
384
385 filter.append(StringPool.OPEN_PARENTHESIS);
386 filter.append(userMappings.getProperty("screenName"));
387 filter.append(StringPool.EQUAL);
388 filter.append(screenName);
389 filter.append(StringPool.CLOSE_PARENTHESIS);
390
391 SearchControls searchControls = new SearchControls(
392 SearchControls.SUBTREE_SCOPE, 1, 0, null, false, false);
393
394 enu = ldapContext.search(baseDN, filter.toString(), searchControls);
395 }
396 catch (Exception e) {
397 throw e;
398 }
399 finally {
400 if (ldapContext != null) {
401 ldapContext.close();
402 }
403 }
404
405 if (enu.hasMoreElements()) {
406 Binding binding = enu.nextElement();
407
408 enu.close();
409
410 return binding;
411 }
412 else {
413 return null;
414 }
415 }
416
417 public static Attributes getUserAttributes(
418 long ldapServerId, long companyId, LdapContext ldapContext,
419 String fullDistinguishedName)
420 throws Exception {
421
422 Properties userMappings = LDAPSettingsUtil.getUserMappings(
423 ldapServerId, companyId);
424
425 String[] mappedUserAttributeIds = {
426 userMappings.getProperty("screenName"),
427 userMappings.getProperty("emailAddress"),
428 userMappings.getProperty("fullName"),
429 userMappings.getProperty("firstName"),
430 userMappings.getProperty("middleName"),
431 userMappings.getProperty("lastName"),
432 userMappings.getProperty("jobTitle"),
433 userMappings.getProperty("group")
434 };
435
436 return _getAttributes(
437 ldapContext, fullDistinguishedName, mappedUserAttributeIds);
438 }
439
440
443 public static Properties getUserMappings(long ldapServerId, long companyId)
444 throws Exception {
445
446 return LDAPSettingsUtil.getUserMappings(ldapServerId, companyId);
447 }
448
449 public static byte[] getUsers(
450 long companyId, LdapContext ldapContext, byte[] cookie,
451 int maxResults, String baseDN, String userFilter,
452 List<SearchResult> searchResults)
453 throws Exception {
454
455 return searchLDAP(
456 companyId, ldapContext, cookie, maxResults, baseDN, userFilter,
457 null, searchResults);
458 }
459
460 public static byte[] getUsers(
461 long companyId, LdapContext ldapContext, byte[] cookie,
462 int maxResults, String baseDN, String userFilter,
463 String[] attributeIds, List<SearchResult> searchResults)
464 throws Exception {
465
466 return searchLDAP(
467 companyId, ldapContext, cookie, maxResults, baseDN, userFilter,
468 attributeIds, searchResults);
469 }
470
471 public static byte[] getUsers(
472 long ldapServerId, long companyId, LdapContext ldapContext,
473 byte[] cookie, int maxResults, List<SearchResult> searchResults)
474 throws Exception {
475
476 String postfix = LDAPSettingsUtil.getPropertyPostfix(ldapServerId);
477
478 String baseDN = PrefsPropsUtil.getString(
479 companyId, PropsKeys.LDAP_BASE_DN + postfix);
480 String userFilter = PrefsPropsUtil.getString(
481 companyId, PropsKeys.LDAP_IMPORT_USER_SEARCH_FILTER + postfix);
482
483 return getUsers(
484 companyId, ldapContext, cookie, maxResults, baseDN, userFilter,
485 searchResults);
486 }
487
488 public static byte[] getUsers(
489 long ldapServerId, long companyId, LdapContext ldapContext,
490 byte[] cookie, int maxResults, String[] attributeIds,
491 List<SearchResult> searchResults)
492 throws Exception {
493
494 String postfix = LDAPSettingsUtil.getPropertyPostfix(ldapServerId);
495
496 String baseDN = PrefsPropsUtil.getString(
497 companyId, PropsKeys.LDAP_BASE_DN + postfix);
498 String userFilter = PrefsPropsUtil.getString(
499 companyId, PropsKeys.LDAP_IMPORT_USER_SEARCH_FILTER + postfix);
500
501 return getUsers(
502 companyId, ldapContext, cookie, maxResults, baseDN, userFilter,
503 attributeIds, searchResults);
504 }
505
506 public static String getUsersDN(long ldapServerId, long companyId)
507 throws Exception {
508
509 String postfix = LDAPSettingsUtil.getPropertyPostfix(ldapServerId);
510
511 return PrefsPropsUtil.getString(
512 companyId, PropsKeys.LDAP_USERS_DN + postfix);
513 }
514
515 public static boolean hasUser(
516 long ldapServerId, long companyId, String screenName)
517 throws Exception {
518
519 if (getUser(ldapServerId, companyId, screenName) != null) {
520 return true;
521 }
522 else {
523 return false;
524 }
525 }
526
527
530 public static void importFromLDAP() throws Exception {
531 PortalLDAPImporter.importFromLDAP();
532 }
533
534
537 public static void importFromLDAP(long companyId) throws Exception {
538 PortalLDAPImporter.importFromLDAP(companyId);
539 }
540
541
544 public static void importFromLDAP(long ldapServerId, long companyId)
545 throws Exception {
546
547 PortalLDAPImporter.importFromLDAP(ldapServerId, companyId);
548 }
549
550
554 public static UserGroup importLDAPGroup(
555 long ldapServerId, long companyId, LdapContext ldapContext,
556 Attributes attributes, boolean importGroupMembership)
557 throws Exception {
558
559 return PortalLDAPImporter.importLDAPGroup(
560 ldapServerId, companyId, ldapContext, attributes,
561 importGroupMembership);
562 }
563
564
568 public static User importLDAPUser(
569 long ldapServerId, long companyId, LdapContext ldapContext,
570 Attributes attributes, String password,
571 boolean importGroupMembership)
572 throws Exception {
573
574 return PortalLDAPImporter.importLDAPUser(
575 ldapServerId, companyId, ldapContext, attributes, password,
576 importGroupMembership);
577 }
578
579
582 public static boolean isAuthEnabled(long companyId) throws SystemException {
583 return AuthSettingsUtil.isLDAPAuthEnabled(companyId);
584 }
585
586
589 public static boolean isExportEnabled(long companyId)
590 throws SystemException {
591
592 return LDAPSettingsUtil.isExportEnabled(companyId);
593 }
594
595
598 public static boolean isImportEnabled(long companyId)
599 throws SystemException {
600
601 return LDAPSettingsUtil.isImportEnabled(companyId);
602 }
603
604
607 public static boolean isImportOnStartup(long companyId)
608 throws SystemException {
609
610 return LDAPSettingsUtil.isImportOnStartup(companyId);
611 }
612
613
616 public static boolean isNtlmEnabled(long companyId)
617 throws SystemException {
618
619 return AuthSettingsUtil.isNtlmEnabled(companyId);
620 }
621
622
625 public static boolean isPasswordPolicyEnabled(long companyId)
626 throws SystemException {
627
628 return LDAPSettingsUtil.isPasswordPolicyEnabled(companyId);
629 }
630
631
634 public static boolean isSiteMinderEnabled(long companyId)
635 throws SystemException {
636
637 return AuthSettingsUtil.isSiteMinderEnabled(companyId);
638 }
639
640 public static byte[] searchLDAP(
641 long companyId, LdapContext ldapContext, byte[] cookie,
642 int maxResults, String baseDN, String filter,
643 String[] attributeIds, List<SearchResult> searchResults)
644 throws Exception {
645
646 SearchControls searchControls = new SearchControls(
647 SearchControls.SUBTREE_SCOPE, maxResults, 0, attributeIds, false,
648 false);
649
650 try {
651 if (cookie != null) {
652 if (cookie.length == 0) {
653 ldapContext.setRequestControls(
654 new Control[] {
655 new PagedResultsControl(
656 PropsValues.LDAP_PAGE_SIZE, Control.CRITICAL)
657 });
658 }
659 else {
660 ldapContext.setRequestControls(
661 new Control[] {
662 new PagedResultsControl(
663 PropsValues.LDAP_PAGE_SIZE, cookie,
664 Control.CRITICAL)
665 });
666 }
667
668 NamingEnumeration<SearchResult> enu = ldapContext.search(
669 baseDN, filter, searchControls);
670
671 while (enu.hasMoreElements()) {
672 searchResults.add(enu.nextElement());
673 }
674
675 enu.close();
676
677 return _getCookie(ldapContext.getResponseControls());
678 }
679 }
680 catch (OperationNotSupportedException onse) {
681 ldapContext.setRequestControls(null);
682
683 NamingEnumeration<SearchResult> enu = ldapContext.search(
684 baseDN, filter, searchControls);
685
686 while (enu.hasMoreElements()) {
687 searchResults.add(enu.nextElement());
688 }
689
690 enu.close();
691 }
692 finally {
693 ldapContext.setRequestControls(null);
694 }
695
696 return null;
697 }
698
699 private static Attributes _getAttributes(
700 LdapContext ldapContext, String fullDistinguishedName,
701 String[] attributeIds)
702 throws Exception {
703
704 Name fullDN = new CompositeName().add(fullDistinguishedName);
705
706 Attributes attributes = null;
707
708 String[] auditAttributeIds = {
709 "creatorsName", "createTimestamp", "modifiersName",
710 "modifyTimestamp"
711 };
712
713 if (attributeIds == null) {
714
715
717 attributes = ldapContext.getAttributes(fullDN);
718
719 NamingEnumeration<? extends Attribute> enu =
720 ldapContext.getAttributes(fullDN, auditAttributeIds).getAll();
721
722 while (enu.hasMoreElements()) {
723 attributes.put(enu.nextElement());
724 }
725
726 enu.close();
727 }
728 else {
729
730
732 int attributeCount = attributeIds.length + auditAttributeIds.length;
733
734 String[] allAttributeIds = new String[attributeCount];
735
736 System.arraycopy(
737 attributeIds, 0, allAttributeIds, 0, attributeIds.length);
738 System.arraycopy(
739 auditAttributeIds, 0, allAttributeIds, attributeIds.length,
740 auditAttributeIds.length);
741
742 attributes = ldapContext.getAttributes(fullDN, allAttributeIds);
743 }
744
745 return attributes;
746 }
747
748 private static byte[] _getCookie(Control[] controls) {
749 if (controls == null) {
750 return null;
751 }
752
753 for (Control control : controls) {
754 if (control instanceof PagedResultsResponseControl) {
755 PagedResultsResponseControl pagedResultsResponseControl =
756 (PagedResultsResponseControl)control;
757
758 return pagedResultsResponseControl.getCookie();
759 }
760 }
761
762 return null;
763 }
764
765 private static String _getNextRange(String attributeId) {
766 String originalAttributeId = null;
767 int start = 0;
768 int end = 0;
769
770 int x = attributeId.indexOf(CharPool.SEMICOLON);
771
772 if (x < 0) {
773 originalAttributeId = attributeId;
774 end = PropsValues.LDAP_RANGE_SIZE - 1;
775 }
776 else {
777 int y = attributeId.indexOf(CharPool.EQUAL, x);
778 int z = attributeId.indexOf(CharPool.DASH, y);
779
780 originalAttributeId = attributeId.substring(0, x);
781 start = GetterUtil.getInteger(attributeId.substring(y + 1, z));
782 end = GetterUtil.getInteger(attributeId.substring(z + 1));
783
784 start += PropsValues.LDAP_RANGE_SIZE;
785 end += PropsValues.LDAP_RANGE_SIZE;
786 }
787
788 StringBundler sb = new StringBundler(6);
789
790 sb.append(originalAttributeId);
791 sb.append(StringPool.SEMICOLON);
792 sb.append("range=");
793 sb.append(start);
794 sb.append(StringPool.DASH);
795 sb.append(end);
796
797 return sb.toString();
798 }
799
800 private static Log _log = LogFactoryUtil.getLog(PortalLDAPUtil.class);
801
802 }