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
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) {
Copy link
Contributor

Choose a reason for hiding this comment

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

we only need to do this if isIBM(). Would it be better to just add this in Util.isIBM()?

Copy link
Contributor

@machavan machavan Jan 28, 2025

Choose a reason for hiding this comment

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

@lilgreenbird The issue was reported due to a problem with Util.isIBM method implementation ( #2139)

Do you mean just adding the try catch logic in Util.isIBM method to improve it and leaving everything else unchanged?

So something like this ?

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

        String vmName = System.getProperty("java.vm.name");
        if (SYSTEM_JRE.startsWith("IBM") && 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;
    }

Copy link
Contributor

Choose a reason for hiding this comment

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

yes that's what I meant :)

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
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 @@ -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();
muskan124947 marked this conversation as resolved.
Show resolved Hide resolved
}

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