Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed issue for IBM Semeru Runtime Certified Edition for z/OS and Kerberos #2581

Merged
merged 12 commits into from
Feb 11, 2025
39 changes: 27 additions & 12 deletions src/main/java/com/microsoft/sqlserver/jdbc/JaasConfiguration.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,39 @@
private final Configuration delegate;
private AppConfigurationEntry[] defaultValue;

private static AppConfigurationEntry[] generateDefaultConfiguration() {
if (Util.isIBM()) {
private static boolean useIbmModule = false;

Check warning on line 22 in src/main/java/com/microsoft/sqlserver/jdbc/JaasConfiguration.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/microsoft/sqlserver/jdbc/JaasConfiguration.java#L22

Added line #L22 was not covered by tests

private static AppConfigurationEntry[] generateDefaultConfiguration() throws SQLServerException {
try {
if (useIbmModule) {
return loadIbmModule();

Check warning on line 27 in src/main/java/com/microsoft/sqlserver/jdbc/JaasConfiguration.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/microsoft/sqlserver/jdbc/JaasConfiguration.java#L27

Added line #L27 was not covered by tests
}
Class.forName("com.sun.security.auth.module.Krb5LoginModule");
Map<String, String> confDetails = new HashMap<>();
confDetails.put("useTicketCache", "true");
return new AppConfigurationEntry[] {

Check warning on line 32 in src/main/java/com/microsoft/sqlserver/jdbc/JaasConfiguration.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/microsoft/sqlserver/jdbc/JaasConfiguration.java#L29-L32

Added lines #L29 - L32 were not covered by tests
new AppConfigurationEntry("com.sun.security.auth.module.Krb5LoginModule",
AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, confDetails)};
} catch (ClassNotFoundException e) {
return loadIbmModule();

Check warning on line 36 in src/main/java/com/microsoft/sqlserver/jdbc/JaasConfiguration.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/microsoft/sqlserver/jdbc/JaasConfiguration.java#L35-L36

Added lines #L35 - L36 were not covered by tests
}
}

private static AppConfigurationEntry[] loadIbmModule() throws SQLServerException {
try {
Class.forName("com.ibm.security.auth.module.Krb5LoginModule");
useIbmModule = true;

Check warning on line 43 in src/main/java/com/microsoft/sqlserver/jdbc/JaasConfiguration.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/microsoft/sqlserver/jdbc/JaasConfiguration.java#L42-L43

Added lines #L42 - L43 were not covered by tests
Map<String, String> confDetailsWithoutPassword = new HashMap<>();
confDetailsWithoutPassword.put("useDefaultCcache", "true");
Map<String, String> confDetailsWithPassword = new HashMap<>();
// We generated a two configurations fallback that is suitable for password and password-less authentication
// See
// https://www.ibm.com/support/knowledgecenter/SSYKE2_8.0.0/com.ibm.java.security.component.80.doc/security-component/jgssDocs/jaas_login_user.html
final String ibmLoginModule = "com.ibm.security.auth.module.Krb5LoginModule";
return new AppConfigurationEntry[] {
new AppConfigurationEntry(ibmLoginModule, AppConfigurationEntry.LoginModuleControlFlag.SUFFICIENT,
confDetailsWithoutPassword),
new AppConfigurationEntry(ibmLoginModule, AppConfigurationEntry.LoginModuleControlFlag.SUFFICIENT,
confDetailsWithPassword)};
} else {
Map<String, String> confDetails = new HashMap<>();
confDetails.put("useTicketCache", "true");
return new AppConfigurationEntry[] {
new AppConfigurationEntry("com.sun.security.auth.module.Krb5LoginModule",
AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, confDetails)};
} catch (ClassNotFoundException ex) {
throw new SQLServerException(SQLServerException.getErrString("R_moduleNotFound"), null);

Check warning on line 54 in src/main/java/com/microsoft/sqlserver/jdbc/JaasConfiguration.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/microsoft/sqlserver/jdbc/JaasConfiguration.java#L53-L54

Added lines #L53 - L54 were not covered by tests
}
}

Expand All @@ -47,8 +60,10 @@
*
* @param delegate
* a possibly null delegate
* @throws SQLServerException
* if neither Kerberos module is found: com.sun.security.auth.module.Krb5LoginModule or com.ibm.security.auth.module.Krb5LoginModule
*/
JaasConfiguration(Configuration delegate) {
JaasConfiguration(Configuration delegate) throws SQLServerException {

Check warning on line 66 in src/main/java/com/microsoft/sqlserver/jdbc/JaasConfiguration.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/microsoft/sqlserver/jdbc/JaasConfiguration.java#L66

Added line #L66 was not covered by tests
this.delegate = delegate;
this.defaultValue = generateDefaultConfiguration();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,11 @@
static {
// Overrides the default JAAS configuration loader.
// This one will forward to the default one in all cases but the default configuration is empty.
Configuration.setConfiguration(new JaasConfiguration(Configuration.getConfiguration()));
try {
Configuration.setConfiguration(new JaasConfiguration(Configuration.getConfiguration()));
} catch (SQLServerException e) {
e.printStackTrace();
}

Check warning on line 52 in src/main/java/com/microsoft/sqlserver/jdbc/KerbAuthentication.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/microsoft/sqlserver/jdbc/KerbAuthentication.java#L49-L52

Added lines #L49 - L52 were not covered by tests
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,7 @@ protected Object[][] getContents() {
{"R_InvalidRuleFormat", "Wrong number of parameters supplied to rule. Number of parameters: {0}, expected: 2 or 3."},
{"R_InvalidRetryInterval", "Current retry interval: {0}, is longer than queryTimeout: {1}."},
{"R_UnableToFindClass", "Unable to locate specified class: {0}"},
{"R_moduleNotFound", "Neither com.sun.security.auth.module.Krb5LoginModule nor com.ibm.security.auth.module.Krb5LoginModule was found."},
};
}
// @formatter:on
22 changes: 22 additions & 0 deletions src/test/java/com/microsoft/sqlserver/jdbc/KerberosTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,28 @@ private static void createKerberosConnection(String connectionString) throws Exc
}
}

/**
* Test to verify the Kerberos module used
*/
@Test
public void testKerberosConnectionWithDefaultJaasConfig() {
try {
// Set a mock JAAS configuration using the existing method
overwriteJaasConfig();

String connectionString = connectionStringKerberos + ";useDefaultJaasConfig=true;";
createKerberosConnection(connectionString);

Configuration config = Configuration.getConfiguration();
AppConfigurationEntry[] entries = config.getAppConfigurationEntry("CLIENT_CONTEXT_NAME");
Assertions.assertNotNull(entries);
Assertions.assertTrue(entries.length > 0);
Assertions.assertEquals("com.sun.security.auth.module.Krb5LoginModule", entries[0].getLoginModuleName());
} catch (Exception e) {
Assertions.fail("Exception was thrown: " + e.getMessage());
}
}

/**
* Overwrites the default JAAS config. Call before making a connection.
*/
Expand Down
Loading