Skip to content

Commit

Permalink
IBM Semeru Runtime Certified Edition for z/OS, Kerberos and mssql-jdb…
Browse files Browse the repository at this point in the history
…c don't work together #2576 (#2581)

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

* Added test case

* Comment

* Updated test

* Updated the configuration name JAAS

* Testing purpose

* removed local changes

* Added error string and useIbmModule boolean flag

* Update isIBM()

* Updated the logic
  • Loading branch information
muskan124947 authored Feb 11, 2025
1 parent 83072af commit e63814e
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 16 deletions.
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 @@ public class JaasConfiguration extends Configuration {
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();
}
Class.forName("com.sun.security.auth.module.Krb5LoginModule");
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 e) {
throw new SQLServerException(SQLServerException.getErrString("R_moduleNotFound"), null);
}
}

private static AppConfigurationEntry[] loadIbmModule() throws SQLServerException {
try {
Class.forName("com.ibm.security.auth.module.Krb5LoginModule");
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_ibmModuleNotFound"), null);
}
}

Expand All @@ -47,8 +57,10 @@ private static AppConfigurationEntry[] generateDefaultConfiguration() {
*
* @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 {
this.delegate = delegate;
this.defaultValue = generateDefaultConfiguration();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,13 @@ final class KerbAuthentication extends SSPIAuthentication {
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);
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,8 @@ 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_ibmModuleNotFound", "com.ibm.security.auth.module.Krb5LoginModule module was not found."},
{"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 @@ private Util() {
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;
}

try {
Class.forName("com.ibm.security.auth.module.Krb5LoginModule");
isIBM = true;
} catch (ClassNotFoundException ex) {
isIBM = false;
}
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

0 comments on commit e63814e

Please sign in to comment.