# HG changeset patch # User weijun # Date 1432456512 -28800 # Node ID 00f3c40fd3af6a4af2a86879fbf9e3f757cb7b1d # Parent 0291fb74c7b62ca210b0e12beeb92d88500df558 8048030: Expectations should be consistent Reviewed-by: valeriep, mullan, ahgross diff -r 0291fb74c7b6 -r 00f3c40fd3af jdk/src/java.base/share/classes/javax/security/auth/AuthPermission.java --- a/jdk/src/java.base/share/classes/javax/security/auth/AuthPermission.java Sat May 23 02:49:50 2015 +0300 +++ b/jdk/src/java.base/share/classes/javax/security/auth/AuthPermission.java Sun May 24 16:35:12 2015 +0800 @@ -101,6 +101,18 @@ * login Configuration. * * + *

Please note that granting this permission with the "modifyPrincipals", + * "modifyPublicCredentials" or "modifyPrivateCredentials" target allows + * a JAAS login module to populate principal or credential objects into + * the Subject. Although reading information inside the private credentials + * set requires a {@link PrivateCredentialPermission} of the credential type to + * be granted, reading information inside the principals set and the public + * credentials set requires no additional permission. These objects can contain + * potentially sensitive information. For example, login modules that read + * local user information or perform a Kerberos login are able to add + * potentially sensitive information such as user ids, groups and domain names + * to the principals set. + * *

The following target name has been deprecated in favor of * {@code createLoginContext.{name}}. * diff -r 0291fb74c7b6 -r 00f3c40fd3af jdk/src/java.security.jgss/share/classes/javax/security/auth/kerberos/KerberosPrincipal.java --- a/jdk/src/java.security.jgss/share/classes/javax/security/auth/kerberos/KerberosPrincipal.java Sat May 23 02:49:50 2015 +0300 +++ b/jdk/src/java.security.jgss/share/classes/javax/security/auth/kerberos/KerberosPrincipal.java Sun May 24 16:35:12 2015 +0800 @@ -100,9 +100,16 @@ *

If the input name does not contain a realm, the default realm * is used. The default realm can be specified either in a Kerberos * configuration file or via the java.security.krb5.realm - * system property. For more information, + * system property. For more information, see * - * Kerberos Requirements + * Kerberos Requirements. Additionally, if a security manager is + * installed, a {@link ServicePermission} must be granted and the service + * principal of the permission must minimally be inside the + * {@code KerberosPrincipal}'s realm. For example, if the result of + * {@code new KerberosPrincipal("user")} is {@code user@EXAMPLE.COM}, + * then a {@code ServicePermission} with service principal + * {@code host/www.example.com@EXAMPLE.COM} (and any action) + * must be granted. * * @param name the principal name * @throws IllegalArgumentException if name is improperly @@ -110,20 +117,12 @@ * the realm to use and the default realm is not specified * in either a Kerberos configuration file or via the * java.security.krb5.realm system property. + * @throws SecurityException if a security manager is installed and + * {@code name} does not contain the realm to use, and a proper + * {@link ServicePermission} as described above is not granted. */ public KerberosPrincipal(String name) { - - PrincipalName krb5Principal = null; - - try { - // Appends the default realm if it is missing - krb5Principal = new PrincipalName(name, KRB_NT_PRINCIPAL); - } catch (KrbException e) { - throw new IllegalArgumentException(e.getMessage()); - } - nameType = KRB_NT_PRINCIPAL; // default name type - fullName = krb5Principal.toString(); - realm = krb5Principal.getRealmString(); + this(name, KRB_NT_PRINCIPAL); } /** @@ -138,12 +137,19 @@ * name type, KRB_NT_PRINCIPAL where duke * represents a principal, and FOO.COM represents a realm). * - *

If the input name does not contain a realm, the default realm + *

If the input name does not contain a realm, the default realm * is used. The default realm can be specified either in a Kerberos * configuration file or via the java.security.krb5.realm * system property. For more information, see * - * Kerberos Requirements. + * Kerberos Requirements. Additionally, if a security manager is + * installed, a {@link ServicePermission} must be granted and the service + * principal of the permission must minimally be inside the + * {@code KerberosPrincipal}'s realm. For example, if the result of + * {@code new KerberosPrincipal("user")} is {@code user@EXAMPLE.COM}, + * then a {@code ServicePermission} with service principal + * {@code host/www.example.com@EXAMPLE.COM} (and any action) + * must be granted. * * @param name the principal name * @param nameType the name type of the principal @@ -152,6 +158,9 @@ * or if name does not contain the realm to use and the default * realm is not specified in either a Kerberos configuration * file or via the java.security.krb5.realm system property. + * @throws SecurityException if a security manager is installed and + * {@code name} does not contain the realm to use, and a proper + * {@link ServicePermission} as described above is not granted. */ public KerberosPrincipal(String name, int nameType) { @@ -165,6 +174,18 @@ throw new IllegalArgumentException(e.getMessage()); } + if (krb5Principal.isRealmDeduced() && !Realm.AUTODEDUCEREALM) { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + try { + sm.checkPermission(new ServicePermission( + "@" + krb5Principal.getRealmAsString(), "-")); + } catch (SecurityException se) { + // Swallow the actual exception to hide info + throw new SecurityException("Cannot read realm info"); + } + } + } this.nameType = nameType; fullName = krb5Principal.toString(); realm = krb5Principal.getRealmString(); diff -r 0291fb74c7b6 -r 00f3c40fd3af jdk/src/java.security.jgss/share/classes/javax/security/auth/kerberos/ServicePermission.java --- a/jdk/src/java.security.jgss/share/classes/javax/security/auth/kerberos/ServicePermission.java Sat May 23 02:49:50 2015 +0300 +++ b/jdk/src/java.security.jgss/share/classes/javax/security/auth/kerberos/ServicePermission.java Sun May 24 16:35:12 2015 +0800 @@ -51,7 +51,7 @@ * used within. *

* The service principal name is the canonical name of the - * {@code KereberosPrincipal} supplying the service, that is + * {@code KerberosPrincipal} supplying the service, that is * the KerberosPrincipal represents a Kerberos service * principal. This name is treated in a case sensitive manner. * An asterisk may appear by itself, to signify any service principal. @@ -62,6 +62,10 @@ * permission also implies that the TGT can be obtained by an * Authentication Service exchange. *

+ * Granting this permission also implies creating {@link KerberosPrincipal} + * or {@link org.ietf.jgss.GSSName GSSName} without providing a Kerberos + * realm, as long as the permission's service principal is in this realm. + *

* The possible actions are: * *

@@ -146,6 +150,9 @@
      * @param action the action string
      */
     public ServicePermission(String servicePrincipal, String action) {
+        // Note: servicePrincipal can be "@REALM" which means any principal in
+        // this realm implies it. action can be "-" which means any
+        // action implies it.
         super(servicePrincipal);
         init(servicePrincipal, getMask(action));
     }
@@ -208,7 +215,9 @@
 
     boolean impliesIgnoreMask(ServicePermission p) {
         return ((this.getName().equals("*")) ||
-                this.getName().equals(p.getName()));
+                this.getName().equals(p.getName()) ||
+                (p.getName().startsWith("@") &&
+                        this.getName().endsWith(p.getName())));
     }
 
     /**
@@ -318,7 +327,10 @@
     /**
      * Convert an action string to an integer actions mask.
      *
-     * @param action the action string
+     * Note: if action is "-", action will be NONE, which means any
+     * action implies it.
+     *
+     * @param action the action string.
      * @return the action mask
      */
     private static int getMask(String action) {
@@ -335,9 +347,11 @@
 
         char[] a = action.toCharArray();
 
+        if (a.length == 1 && a[0] == '-') {
+            return mask;
+        }
+
         int i = a.length - 1;
-        if (i < 0)
-            return mask;
 
         while (i != -1) {
             char c;
@@ -501,6 +515,17 @@
         ServicePermission np = (ServicePermission) permission;
         int desired = np.getMask();
 
+        if (desired == 0) {
+            for (Permission p: perms.values()) {
+                ServicePermission sp = (ServicePermission)p;
+                if (sp.impliesIgnoreMask(np)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+
         // first, check for wildcard principal
         ServicePermission x = (ServicePermission)perms.get("*");
         if (x != null) {
diff -r 0291fb74c7b6 -r 00f3c40fd3af jdk/src/java.security.jgss/share/classes/org/ietf/jgss/GSSName.java
--- a/jdk/src/java.security.jgss/share/classes/org/ietf/jgss/GSSName.java	Sat May 23 02:49:50 2015 +0300
+++ b/jdk/src/java.security.jgss/share/classes/org/ietf/jgss/GSSName.java	Sun May 24 16:35:12 2015 +0800
@@ -81,6 +81,18 @@
  *                      GSSName.NT_EXPORT_NAME);
  *
  * 
+ * If a security manager is installed, in order to create a {@code GSSName} + * that contains a Kerberos name element without providing its realm, + * a {@link javax.security.auth.kerberos.ServicePermission ServicePermission} + * must be granted and the service principal of the permission must minimally + * be inside the Kerberos name element's realm. For example, if the result of + * {@link GSSManager#createName(String, Oid) createName("user", NT_USER_NAME)} + * contains a Kerberos name element {@code user@EXAMPLE.COM}, then + * a {@code ServicePermission} with service principal + * {@code host/www.example.com@EXAMPLE.COM} (and any action) must be granted. + * Otherwise, the creation will throw a {@link GSSException} containing the + * {@code GSSException.FAILURE} error code. + * * @see #export() * @see #equals(GSSName) * @see GSSManager#createName(String, Oid) diff -r 0291fb74c7b6 -r 00f3c40fd3af jdk/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5NameElement.java --- a/jdk/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5NameElement.java Sat May 23 02:49:50 2015 +0300 +++ b/jdk/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5NameElement.java Sun May 24 16:35:12 2015 +0800 @@ -28,7 +28,10 @@ import org.ietf.jgss.*; import sun.security.jgss.spi.*; import sun.security.krb5.PrincipalName; +import sun.security.krb5.Realm; import sun.security.krb5.KrbException; + +import javax.security.auth.kerberos.ServicePermission; import java.io.UnsupportedEncodingException; import java.net.InetAddress; import java.net.UnknownHostException; @@ -126,6 +129,18 @@ throw new GSSException(GSSException.BAD_NAME, -1, e.getMessage()); } + if (principalName.isRealmDeduced() && !Realm.AUTODEDUCEREALM) { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + try { + sm.checkPermission(new ServicePermission( + "@" + principalName.getRealmAsString(), "-")); + } catch (SecurityException se) { + // Do not chain the actual exception to hide info + throw new GSSException(GSSException.FAILURE); + } + } + } return new Krb5NameElement(principalName, gssNameStr, gssNameType); } diff -r 0291fb74c7b6 -r 00f3c40fd3af jdk/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/GSSNameElement.java --- a/jdk/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/GSSNameElement.java Sat May 23 02:49:50 2015 +0300 +++ b/jdk/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/GSSNameElement.java Sun May 24 16:35:12 2015 +0800 @@ -30,6 +30,7 @@ import java.security.Security; import java.io.IOException; import java.io.UnsupportedEncodingException; +import sun.security.krb5.Realm; import sun.security.jgss.GSSUtil; import sun.security.util.ObjectIdentifier; import sun.security.util.DerInputStream; @@ -38,6 +39,8 @@ import sun.security.jgss.GSSExceptionImpl; import sun.security.jgss.spi.GSSNameSpi; +import javax.security.auth.kerberos.ServicePermission; + /** * This class is essentially a wrapper class for the gss_name_t * structure of the native GSS library. @@ -150,6 +153,26 @@ pName = cStub.importName(name, nameType); setPrintables(); + SecurityManager sm = System.getSecurityManager(); + if (sm != null && !Realm.AUTODEDUCEREALM) { + String krbName = getKrbName(); + int atPos = krbName.lastIndexOf('@'); + if (atPos != -1) { + String atRealm = krbName.substring(atPos); + if (nameType.equals(GSSUtil.NT_GSS_KRB5_PRINCIPAL) + && new String(nameBytes).endsWith(atRealm)) { + // Created from Kerberos name with realm, no need to check + } else { + try { + sm.checkPermission(new ServicePermission(atRealm, "-")); + } catch (SecurityException se) { + // Do not chain the actual exception to hide info + throw new GSSException(GSSException.FAILURE); + } + } + } + } + SunNativeProvider.debug("Imported " + printableName + " w/ type " + printableType); } diff -r 0291fb74c7b6 -r 00f3c40fd3af jdk/src/java.security.jgss/share/classes/sun/security/krb5/KrbServiceLocator.java --- a/jdk/src/java.security.jgss/share/classes/sun/security/krb5/KrbServiceLocator.java Sat May 23 02:49:50 2015 +0300 +++ b/jdk/src/java.security.jgss/share/classes/sun/security/krb5/KrbServiceLocator.java Sun May 24 16:35:12 2015 +0800 @@ -25,6 +25,11 @@ package sun.security.krb5; +import sun.security.krb5.internal.Krb5; + +import java.security.AccessController; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; import java.util.Arrays; import java.util.Hashtable; import java.util.Random; @@ -52,6 +57,8 @@ private static final Random random = new Random(); + private static final boolean DEBUG = Krb5.DEBUG; + private KrbServiceLocator() { } @@ -62,8 +69,7 @@ * Information on the mapping of DNS hostnames and domain names * to Kerberos realms is stored using DNS TXT records * - * @param domainName A string domain name. - * @param environment The possibly null environment of the context. + * @param realmName A string realm name. * @return An ordered list of hostports for the Kerberos service or null if * the service has not been located. */ @@ -81,8 +87,18 @@ if (!(ctx instanceof DirContext)) { return null; // cannot create a DNS context } - Attributes attrs = - ((DirContext)ctx).getAttributes(dnsUrl, SRV_TXT_ATTR); + Attributes attrs = null; + try { + // both connect and accept are needed since DNS is thru UDP + attrs = AccessController.doPrivileged( + (PrivilegedExceptionAction) + () -> ((DirContext)ctx).getAttributes( + dnsUrl, SRV_TXT_ATTR), + null, + new java.net.SocketPermission("*", "connect,accept")); + } catch (PrivilegedActionException e) { + throw (NamingException)e.getCause(); + } Attribute attr; if (attrs != null && ((attr = attrs.get(SRV_TXT)) != null)) { @@ -124,7 +140,8 @@ * Queries DNS for a list of KERBEROS Service Location Records (SRV) for a * given domain name. * - * @param domainName A string domain name. + * @param realmName A string realm name. + * @param protocol the protocol string, can be "_udp" or "_tcp" * @return An ordered list of hostports for the Kerberos service or null if * the service has not been located. */ @@ -142,8 +159,20 @@ if (!(ctx instanceof DirContext)) { return null; // cannot create a DNS context } - Attributes attrs = - ((DirContext)ctx).getAttributes(dnsUrl, SRV_RR_ATTR); + + Attributes attrs = null; + try { + // both connect and accept are needed since DNS is thru UDP + attrs = AccessController.doPrivileged( + (PrivilegedExceptionAction) + () -> ((DirContext)ctx).getAttributes( + dnsUrl, SRV_RR_ATTR), + null, + new java.net.SocketPermission("*", "connect,accept")); + } catch (PrivilegedActionException e) { + throw (NamingException)e.getCause(); + } + Attribute attr; if (attrs != null && ((attr = attrs.get(SRV_RR)) != null)) { diff -r 0291fb74c7b6 -r 00f3c40fd3af jdk/src/java.security.jgss/share/classes/sun/security/krb5/PrincipalName.java --- a/jdk/src/java.security.jgss/share/classes/sun/security/krb5/PrincipalName.java Sat May 23 02:49:50 2015 +0300 +++ b/jdk/src/java.security.jgss/share/classes/sun/security/krb5/PrincipalName.java Sun May 24 16:35:12 2015 +0800 @@ -123,6 +123,13 @@ */ private final Realm nameRealm; // not null + + /** + * When constructing a PrincipalName, whether the realm is included in + * the input, or deduced from default realm or domain-realm mapping. + */ + private final boolean realmDeduced; + // cached default salt, not used in clone private transient String salt = null; @@ -143,6 +150,7 @@ this.nameType = nameType; this.nameStrings = nameStrings.clone(); this.nameRealm = nameRealm; + this.realmDeduced = false; } // This method is called by Windows NativeCred.c @@ -150,11 +158,6 @@ this(KRB_NT_UNKNOWN, nameParts, new Realm(realm)); } - public PrincipalName(String[] nameParts, int type) - throws IllegalArgumentException, RealmException { - this(type, nameParts, Realm.getDefault()); - } - // Validate a nameStrings argument private static void validateNameStrings(String[] ns) { if (ns == null) { @@ -226,7 +229,7 @@ * * http://www.ietf.org/rfc/rfc4120.txt. * - * @param encoding a Der-encoded data. + * @param encoding DER-encoded PrincipalName (without Realm) * @param realm the realm for this name * @exception Asn1Exception if an error occurs while decoding * an ASN1 encoded data. @@ -240,6 +243,7 @@ if (realm == null) { throw new IllegalArgumentException("Null realm not allowed"); } + realmDeduced = false; nameRealm = realm; DerValue der; if (encoding == null) { @@ -394,6 +398,10 @@ if (realm == null) { realm = Realm.parseRealmAtSeparator(name); } + + // No realm info from parameter and string, must deduce later + realmDeduced = realm == null; + switch (type) { case KRB_NT_SRV_HST: if (nameParts.length >= 2) { @@ -413,8 +421,8 @@ hostName.toLowerCase(Locale.ENGLISH)+".")) { hostName = canonicalized; } - } catch (UnknownHostException e) { - // no canonicalization, use old + } catch (UnknownHostException | SecurityException e) { + // not canonicalized or no permission to do so, use old } nameParts[1] = hostName.toLowerCase(Locale.ENGLISH); } @@ -681,4 +689,7 @@ return result; } + public boolean isRealmDeduced() { + return realmDeduced; + } } diff -r 0291fb74c7b6 -r 00f3c40fd3af jdk/src/java.security.jgss/share/classes/sun/security/krb5/Realm.java --- a/jdk/src/java.security.jgss/share/classes/sun/security/krb5/Realm.java Sat May 23 02:49:50 2015 +0300 +++ b/jdk/src/java.security.jgss/share/classes/sun/security/krb5/Realm.java Sun May 24 16:35:12 2015 +0800 @@ -46,6 +46,12 @@ * This class is immutable. */ public class Realm implements Cloneable { + + public static final boolean AUTODEDUCEREALM = + java.security.AccessController.doPrivileged( + new sun.security.action.GetBooleanAction( + "sun.security.krb5.autodeducerealm")); + private final String realm; // not null nor empty public Realm(String name) throws RealmException { diff -r 0291fb74c7b6 -r 00f3c40fd3af jdk/src/java.security.jgss/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java --- a/jdk/src/java.security.jgss/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java Sat May 23 02:49:50 2015 +0300 +++ b/jdk/src/java.security.jgss/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java Sun May 24 16:35:12 2015 +0800 @@ -146,8 +146,9 @@ } try { return new PrincipalName( + type, result.toArray(new String[result.size()]), - type); + Realm.getDefault()); } catch (RealmException re) { return null; } diff -r 0291fb74c7b6 -r 00f3c40fd3af jdk/test/sun/security/krb5/auto/KDC.java --- a/jdk/test/sun/security/krb5/auto/KDC.java Sat May 23 02:49:50 2015 +0300 +++ b/jdk/test/sun/security/krb5/auto/KDC.java Sun May 24 16:35:12 2015 +0800 @@ -889,8 +889,9 @@ PrincipalName service = asReq.reqBody.sname; if (options.containsKey(KDC.Option.RESP_NT)) { - service = new PrincipalName(service.getNameStrings(), - (int)options.get(KDC.Option.RESP_NT)); + service = new PrincipalName((int)options.get(KDC.Option.RESP_NT), + service.getNameStrings(), + Realm.getDefault()); } try { System.out.println(realm + "> " + asReq.reqBody.cname + diff -r 0291fb74c7b6 -r 00f3c40fd3af jdk/test/sun/security/krb5/auto/SSL.java --- a/jdk/test/sun/security/krb5/auto/SSL.java Sat May 23 02:49:50 2015 +0300 +++ b/jdk/test/sun/security/krb5/auto/SSL.java Sun May 24 16:35:12 2015 +0800 @@ -76,7 +76,10 @@ return; } ServicePermission p = (ServicePermission)perm; - permChecks = permChecks + p.getActions().toUpperCase().charAt(0); + // ServicePermissions required to create GSSName are ignored + if (!p.getActions().isEmpty()) { + permChecks = permChecks + p.getActions().toUpperCase().charAt(0); + } } public static void main(String[] args) throws Exception { diff -r 0291fb74c7b6 -r 00f3c40fd3af jdk/test/sun/security/krb5/name/Constructors.java --- a/jdk/test/sun/security/krb5/name/Constructors.java Sat May 23 02:49:50 2015 +0300 +++ b/jdk/test/sun/security/krb5/name/Constructors.java Sun May 24 16:35:12 2015 +0800 @@ -41,22 +41,22 @@ // Good ones type = PrincipalName.KRB_NT_UNKNOWN; - checkName("a", type, "R", "R", "a"); - checkName("a@R2", type, "R", "R", "a"); - checkName("a/b", type, "R", "R", "a", "b"); - checkName("a/b@R2", type, "R", "R", "a", "b"); - checkName("a/b/c", type, "R", "R", "a", "b", "c"); - checkName("a/b/c@R2", type, "R", "R", "a", "b", "c"); + checkName("a", type, "R", "R", false, "a"); + checkName("a@R2", type, "R", "R", false, "a"); + checkName("a/b", type, "R", "R", false, "a", "b"); + checkName("a/b@R2", type, "R", "R", false, "a", "b"); + checkName("a/b/c", type, "R", "R", false, "a", "b", "c"); + checkName("a/b/c@R2", type, "R", "R", false, "a", "b", "c"); // Weird ones - checkName("a\\/b", type, "R", "R", "a/b"); - checkName("a\\/b\\/c", type, "R", "R", "a/b/c"); - checkName("a\\/b\\@R2", type, "R", "R", "a/b@R2"); + checkName("a\\/b", type, "R", "R", false, "a/b"); + checkName("a\\/b\\/c", type, "R", "R", false, "a/b/c"); + checkName("a\\/b\\@R2", type, "R", "R", false, "a/b@R2"); // Bad ones - checkName("a", type, "", null); - checkName("a/", type, "R", null); - checkName("/a", type, "R", null); - checkName("a//b", type, "R", null); - checkName("a@", type, null, null); + checkName("a", type, "", null, false); + checkName("a/", type, "R", null, false); + checkName("/a", type, "R", null, false); + checkName("a//b", type, "R", null, false); + checkName("a@", type, null, null, false); type = PrincipalName.KRB_NT_SRV_HST; // Part 2: on realm choices @@ -78,17 +78,17 @@ if (testNoDefaultDomain) { type = PrincipalName.KRB_NT_UNKNOWN; - checkName("a", type, "R1", "R1", "a"); // arg - checkName("a@R1", type, null, "R1", "a"); // or r in name - checkName("a@R2", type, "R1", "R1", "a"); // arg over r - checkName("a", type, null, null); // fail if none - checkName("a/b@R1", type, null, "R1", "a", "b"); + checkName("a", type, "R1", "R1", false, "a"); // arg + checkName("a@R1", type, null, "R1", false, "a"); // or r in name + checkName("a@R2", type, "R1", "R1", false, "a"); // arg over r + checkName("a", type, null, null, false); // fail if none + checkName("a/b@R1", type, null, "R1", false, "a", "b"); type = PrincipalName.KRB_NT_SRV_HST; // Let's pray "b.h" won't be canonicalized - checkName("a/b.h", type, "R1", "R1", "a", "b.h"); // arg - checkName("a/b.h@R1", type, null, "R1", "a", "b.h"); // or r in name - checkName("a/b.h@R1", type, "R2", "R2", "a", "b.h"); // arg over r - checkName("a/b.h", type, null, null); // fail if none + checkName("a/b.h", type, "R1", "R1", false, "a", "b.h"); // arg + checkName("a/b.h@R1", type, null, "R1", false, "a", "b.h"); // or r in name + checkName("a/b.h@R1", type, "R2", "R2", false, "a", "b.h"); // arg over r + checkName("a/b.h", type, null, null, false); // fail if none } // When there is default realm @@ -97,25 +97,25 @@ Config.refresh(); type = PrincipalName.KRB_NT_UNKNOWN; - checkName("a", type, "R1", "R1", "a"); // arg - checkName("a@R1", type, null, "R1", "a"); // or r in name - checkName("a@R2", type, "R1", "R1", "a"); // arg over r - checkName("a", type, null, "R", "a"); // default - checkName("a/b", type, null, "R", "a", "b"); + checkName("a", type, "R1", "R1", false, "a"); // arg + checkName("a@R1", type, null, "R1", false, "a"); // or r in name + checkName("a@R2", type, "R1", "R1", false, "a"); // arg over r + checkName("a", type, null, "R", true, "a"); // default + checkName("a/b", type, null, "R", true, "a", "b"); type = PrincipalName.KRB_NT_SRV_HST; - checkName("a/b.h3", type, "R1", "R1", "a", "b.h3"); // arg - checkName("a/b.h@R1", type, null, "R1", "a", "b.h"); // or r in name - checkName("a/b.h3@R2", type, "R1", "R1", "a", "b.h3"); // arg over r - checkName("a/b.h2", type, "R1", "R1", "a", "b.h2"); // arg over map - checkName("a/b.h2@R1", type, null, "R1", "a", "b.h2"); // r over map - checkName("a/b.h2", type, null, "R2", "a", "b.h2"); // map - checkName("a/b.h", type, null, "R", "a", "b.h"); // default + checkName("a/b.h3", type, "R1", "R1", false, "a", "b.h3"); // arg + checkName("a/b.h@R1", type, null, "R1", false, "a", "b.h"); // or r in name + checkName("a/b.h3@R2", type, "R1", "R1", false, "a", "b.h3"); // arg over r + checkName("a/b.h2", type, "R1", "R1", false, "a", "b.h2"); // arg over map + checkName("a/b.h2@R1", type, null, "R1", false, "a", "b.h2"); // r over map + checkName("a/b.h2", type, null, "R2", true, "a", "b.h2"); // map + checkName("a/b.h", type, null, "R", true, "a", "b.h"); // default } // Check if the creation matches the expected output. // Note: realm == null means creation failure static void checkName(String n, int t, String s, - String realm, String... parts) + String realm, boolean deduced, String... parts) throws Exception { PrincipalName pn = null; try { @@ -132,5 +132,8 @@ throw new Exception(pn.toString() + " vs " + Arrays.toString(parts) + "@" + realm); } + if (deduced != pn.isRealmDeduced()) { + throw new Exception("pn.realmDeduced is " + pn.isRealmDeduced()); + } } }