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

IBM Semeru Runtime Certified Edition for z/OS, Kerberos and mssql-jdbc don't work together #2576 #2581

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
36 changes: 24 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,36 @@
private final Configuration delegate;
private AppConfigurationEntry[] defaultValue;

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

Check warning on line 25 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#L25

Added line #L25 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 30 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-L30

Added lines #L27 - L30 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 34 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#L33-L34

Added lines #L33 - L34 were not covered by tests
}
}

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

Check warning on line 40 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#L40

Added line #L40 was 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 51 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#L50-L51

Added lines #L50 - L51 were not covered by tests
}
}

Expand All @@ -47,8 +57,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 63 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#L63

Added line #L63 was not covered by tests
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

codecov error, need a test case for this

this.delegate = delegate;
this.defaultValue = generateDefaultConfiguration();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,13 @@
private GSSContext peerContext = null;

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 {
// 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()));
} catch (SQLServerException e) {
throw new RuntimeException("Failed to set JAAS configuration: " + e.getMessage(), e);
}

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 @@ -557,6 +557,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
19 changes: 18 additions & 1 deletion src/main/java/com/microsoft/sqlserver/jdbc/Util.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,26 @@
static final String SYSTEM_JRE = System.getProperty("java.vendor") + " " + System.getProperty("java.version");
private static final Lock LOCK = new ReentrantLock();

private static Boolean isIBM = null;

static boolean isIBM() {
if (isIBM != null) {
return isIBM;
}

String vmName = System.getProperty("java.vm.name");
return SYSTEM_JRE.startsWith("IBM") && vmName.startsWith("IBM");
if (vmName != null && vmName.startsWith("IBM")) {
isIBM = true;
return isIBM;

Check warning on line 60 in src/main/java/com/microsoft/sqlserver/jdbc/Util.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/microsoft/sqlserver/jdbc/Util.java#L59-L60

Added lines #L59 - L60 were not covered by tests
}

try {
Class.forName("com.ibm.security.auth.module.Krb5LoginModule");
isIBM = true;

Check warning on line 65 in src/main/java/com/microsoft/sqlserver/jdbc/Util.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/microsoft/sqlserver/jdbc/Util.java#L64-L65

Added lines #L64 - L65 were not covered by tests
} catch (ClassNotFoundException ex) {
isIBM = false;
}

Check warning on line 68 in src/main/java/com/microsoft/sqlserver/jdbc/Util.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/microsoft/sqlserver/jdbc/Util.java#L68

Added line #L68 was not covered by tests
return isIBM;
}

static String getJVMArchOnWindows() {
Expand Down
39 changes: 39 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,45 @@ 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);
if (Util.isIBM()) {
Assertions.assertEquals("com.ibm.security.auth.module.Krb5LoginModule", entries[0].getLoginModuleName());
} else {
Assertions.assertEquals("com.sun.security.auth.module.Krb5LoginModule", entries[0].getLoginModuleName());
}
} catch (Exception e) {
Assertions.fail("Exception was thrown: " + e.getMessage());
}
}

/**
* Test to verify the JaasConfiguration constructor
*/
@Test
public void testJaasConfigurationConstructor() {
try {
JaasConfiguration config = new JaasConfiguration(Configuration.getConfiguration());
Assertions.assertNotNull(config);
} catch (SQLServerException e) {
Assertions.fail("Exception was thrown: " + e.getMessage());
}
}

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