diff --git a/src/java.security.jgss/share/classes/sun/security/krb5/Config.java b/src/java.security.jgss/share/classes/sun/security/krb5/Config.java index b5601b9bef1..16700e9157e 100644 --- a/src/java.security.jgss/share/classes/sun/security/krb5/Config.java +++ b/src/java.security.jgss/share/classes/sun/security/krb5/Config.java @@ -1268,7 +1268,7 @@ public class Config { if (defaultKDC != null) { return defaultKDC; } - KrbException ke = new KrbException("Cannot locate KDC"); + KrbException ke = new KrbException("Cannot locate KDC for " + realm); if (cause != null) { ke.initCause(cause); } diff --git a/src/java.security.jgss/share/classes/sun/security/krb5/internal/CredentialsUtil.java b/src/java.security.jgss/share/classes/sun/security/krb5/internal/CredentialsUtil.java index 223810f67b5..f2c7dbc956f 100644 --- a/src/java.security.jgss/share/classes/sun/security/krb5/internal/CredentialsUtil.java +++ b/src/java.security.jgss/share/classes/sun/security/krb5/internal/CredentialsUtil.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -326,18 +326,30 @@ public class CredentialsUtil { PrincipalName user, Credentials additionalCreds, PAData[] extraPAs, S4U2Type s4u2Type) throws KrbException, IOException { + KrbException ke = null; if (!Config.DISABLE_REFERRALS) { try { return serviceCredsReferrals(options, asCreds, cname, sname, s4u2Type, user, additionalCreds, extraPAs); } catch (KrbException e) { + ke = e; // Server may raise an error if CANONICALIZE is true. // Try CANONICALIZE false. } } - return serviceCredsSingle(options, asCreds, cname, - asCreds.getClientAlias(), sname, sname, s4u2Type, - user, additionalCreds, extraPAs); + try { + return serviceCredsSingle(options, asCreds, cname, + asCreds.getClientAlias(), sname, sname, s4u2Type, + user, additionalCreds, extraPAs); + } catch (KrbException ke2) { + if (ke != null) { + // Still throw original exception + ke.addSuppressed(ke2); + throw ke; + } else { + throw ke2; + } + } } /* diff --git a/test/jdk/sun/security/krb5/auto/ReferralsTest.java b/test/jdk/sun/security/krb5/auto/ReferralsTest.java index 178bd54a23a..248ba5624a3 100644 --- a/test/jdk/sun/security/krb5/auto/ReferralsTest.java +++ b/test/jdk/sun/security/krb5/auto/ReferralsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Red Hat, Inc. + * Copyright (c) 2019, 2023, Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,13 +23,12 @@ /* * @test - * @bug 8215032 + * @bug 8215032 8308540 * @library /test/lib * @run main/othervm/timeout=120 -Dsun.security.krb5.debug=true ReferralsTest * @summary Test Kerberos cross-realm referrals (RFC 6806) */ -import java.io.File; import java.security.Principal; import java.util.Arrays; import java.util.HashMap; @@ -51,6 +50,8 @@ public class ReferralsTest { private static final String krbConfigName = "krb5-localkdc.conf"; private static final String krbConfigNameNoCanonicalize = "krb5-localkdc-nocanonicalize.conf"; + private static final String krbConfigNameOnlyOne = + "krb5-localkdc-onlyone.conf"; private static final String realmKDC1 = "RABBIT.HOLE"; private static final String realmKDC2 = "DEV.RABBIT.HOLE"; private static final char[] password = "123qwe@Z".toCharArray(); @@ -98,16 +99,13 @@ public class ReferralsTest { PrincipalName.NAME_REALM_SEPARATOR_STR + realmKDC2; public static void main(String[] args) throws Exception { - try { - initializeKDCs(); - testSubjectCredentials(); - testDelegation(); - testImpersonation(); - testDelegationWithReferrals(); - testNoCanonicalize(); - } finally { - cleanup(); - } + initializeKDCs(); + testSubjectCredentials(); + testDelegation(); + testImpersonation(); + testDelegationWithReferrals(); + testNoCanonicalize(); + testOnlyOne(); } private static void initializeKDCs() throws Exception { @@ -147,20 +145,11 @@ public class ReferralsTest { "forwardable=true", "canonicalize=true"); KDC.saveConfig(krbConfigNameNoCanonicalize, kdc1, kdc2, "forwardable=true"); + KDC.saveConfig(krbConfigNameOnlyOne, kdc1, + "forwardable=true", "canonicalize=true"); System.setProperty("java.security.krb5.conf", krbConfigName); } - private static void cleanup() { - String[] configFiles = new String[]{krbConfigName, - krbConfigNameNoCanonicalize}; - for (String configFile : configFiles) { - File f = new File(configFile); - if (f.exists()) { - f.delete(); - } - } - } - /* * The client subject (whose principal is * test@RABBIT.HOLE@RABBIT.HOLE) will obtain a TGT after @@ -375,4 +364,21 @@ public class ReferralsTest { // expected } } + + // For JDK-8308540. When a KDC is not found, provide better error info. + private static void testOnlyOne() throws Exception { + System.setProperty("java.security.krb5.conf", krbConfigNameOnlyOne); + Config.refresh(); + Context c = Context.fromUserPass(userKDC1Name, password, false); + c.startAsClient(serviceName, GSSUtil.GSS_KRB5_MECH_OID); + try { + Context.handshake(c, null); + throw new RuntimeException("Should not succeed"); + } catch (Exception le) { + if (le.getMessage().contains("Cannot locate KDC for DEV.RABBIT.HOLE")) { + return; + } + throw le; + } + } }