1. /*
  2. * @(#)SubjectDelegator.java 1.3 04/05/27
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package com.sun.jmx.remote.security;
  8. import java.security.AccessController;
  9. import java.security.AccessControlContext;
  10. import java.security.Permission;
  11. import java.security.Principal;
  12. import java.security.PrivilegedAction;
  13. import javax.security.auth.Subject;
  14. import javax.management.remote.SubjectDelegationPermission;
  15. import com.sun.jmx.remote.util.CacheMap;
  16. public class SubjectDelegator {
  17. private static final int PRINCIPALS_CACHE_SIZE = 10;
  18. private static final int ACC_CACHE_SIZE = 10;
  19. private CacheMap principalsCache;
  20. private CacheMap accCache;
  21. /* Return the AccessControlContext appropriate to execute an
  22. operation on behalf of the delegatedSubject. If the
  23. authenticatedAccessControlContext does not have permission to
  24. delegate to that subject, throw SecurityException. */
  25. public synchronized AccessControlContext
  26. delegatedContext(AccessControlContext authenticatedACC,
  27. Subject delegatedSubject)
  28. throws SecurityException {
  29. if (principalsCache == null || accCache == null) {
  30. principalsCache = new CacheMap(PRINCIPALS_CACHE_SIZE);
  31. accCache = new CacheMap(ACC_CACHE_SIZE);
  32. }
  33. // Retrieve the principals for the given
  34. // delegated subject from the cache
  35. //
  36. Principal[] delegatedPrincipals = (Principal[])
  37. principalsCache.get(delegatedSubject);
  38. // Convert the set of principals stored in the
  39. // delegated subject into an array of principals
  40. // and store it in the cache
  41. //
  42. if (delegatedPrincipals == null) {
  43. delegatedPrincipals = (Principal[])
  44. delegatedSubject.getPrincipals().toArray(new Principal[0]);
  45. principalsCache.put(delegatedSubject, delegatedPrincipals);
  46. }
  47. // Retrieve the access control context for the
  48. // given delegated subject from the cache
  49. //
  50. AccessControlContext delegatedACC = (AccessControlContext)
  51. accCache.get(delegatedSubject);
  52. // Build the access control context to be used
  53. // when executing code as the delegated subject
  54. // and store it in the cache
  55. //
  56. if (delegatedACC == null) {
  57. delegatedACC =
  58. JMXSubjectDomainCombiner.getContext(delegatedSubject);
  59. accCache.put(delegatedSubject, delegatedACC);
  60. }
  61. // Check if the subject delegation permission allows the
  62. // authenticated subject to assume the identity of each
  63. // principal in the delegated subject
  64. //
  65. final Principal[] dp = delegatedPrincipals;
  66. PrivilegedAction action =
  67. new PrivilegedAction() {
  68. public Object run() {
  69. for (int i = 0 ; i < dp.length ; i++) {
  70. final String pname =
  71. dp[i].getClass().getName() + "." + dp[i].getName();
  72. Permission sdp =
  73. new SubjectDelegationPermission(pname);
  74. AccessController.checkPermission(sdp);
  75. }
  76. return null;
  77. }
  78. };
  79. AccessController.doPrivileged(action, authenticatedACC);
  80. return delegatedACC;
  81. }
  82. }