Skip to content

Commit

Permalink
Merge branch 'main' into ldt-fix
Browse files Browse the repository at this point in the history
  • Loading branch information
tkyc authored Oct 18, 2023
2 parents 66f272d + 7ce903f commit 04d7b85
Show file tree
Hide file tree
Showing 17 changed files with 184 additions and 86 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ allprojects {

test {
useJUnitPlatform {
excludeTags (hasProperty('excludedGroups') ? excludedGroups : 'xSQLv15','xGradle','reqExternalSetup','NTLM','MSI','clientCertAuth','fedAuth')
excludeTags (hasProperty('excludedGroups') ? excludedGroups : 'xSQLv15','xGradle','reqExternalSetup','NTLM','MSI','clientCertAuth','fedAuth','kerberos')
}
}

Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
xAzureSQLDW - - - - For tests not compatible with Azure Data Warehouse -
xAzureSQLMI - - - - For tests not compatible with Azure SQL Managed Instance
NTLM - - - - - - - For tests using NTLM Authentication mode (excluded by default)
Kerberos - - - - - For tests using Kerberos authentication (excluded by default)
kerberos - - - - - For tests using Kerberos authentication (excluded by default)
reqExternalSetup - For tests requiring external setup (excluded by default)
clientCertAuth - - For tests requiring client certificate authentication
setup (excluded by default) - - - - - - - - - - - - - - - - - - - - - - -
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -594,17 +594,32 @@ public interface ISQLServerDataSource extends javax.sql.CommonDataSource {
*/
String getServerSpn();

/**
* Sets the value to indicate whether useDefaultGSSCredential is enabled.
*
* @param enable
* true if useDefaultGSSCredential is enabled. Otherwise, false.
*/
void setUseDefaultGSSCredential(boolean enable);

/**
* Returns the useDefaultGSSCredential.
*
* @return if enabled, return true. Otherwise, false.
*/
boolean getUseDefaultGSSCredential();

/**
* Sets the GSSCredential.
*
*
* @param userCredential
* the credential
*/
void setGSSCredentials(GSSCredential userCredential);

/**
* Returns the GSSCredential.
*
*
* @return GSSCredential
*/
GSSCredential getGSSCredentials();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ final class KerbAuthentication extends SSPIAuthentication {
private LoginContext lc = null;
private boolean isUserCreatedCredential = false;
private GSSCredential peerCredentials = null;
private boolean useDefaultNativeGSSCredential = false;
private GSSContext peerContext = null;

static {
Expand All @@ -63,6 +64,10 @@ private void initAuthInit() throws SQLServerException {
// as it is.
GSSName remotePeerName = manager.createName(spn, null);

if (useDefaultNativeGSSCredential) {
peerCredentials = manager.createCredential(null, GSSCredential.DEFAULT_LIFETIME, kerberos, GSSCredential.INITIATE_ONLY);
}

if (null != peerCredentials) {
peerContext = manager.createContext(remotePeerName, kerberos, peerCredentials,
GSSContext.DEFAULT_LIFETIME);
Expand Down Expand Up @@ -220,10 +225,11 @@ private byte[] initAuthHandShake(byte[] pin, boolean[] done) throws SQLServerExc
* @param impersonatedUserCred
*/
KerbAuthentication(SQLServerConnection con, String address, int port, GSSCredential impersonatedUserCred,
boolean isUserCreated) {
boolean isUserCreated, boolean useDefaultNativeGSSCredential) {
this(con, address, port);
this.peerCredentials = impersonatedUserCred;
this.isUserCreatedCredential = isUserCreated;
this.useDefaultNativeGSSCredential = useDefaultNativeGSSCredential;
}

byte[] generateClientContext(byte[] pin, boolean[] done) throws SQLServerException {
Expand All @@ -235,9 +241,9 @@ byte[] generateClientContext(byte[] pin, boolean[] done) throws SQLServerExcepti

void releaseClientContext() {
try {
if (null != peerCredentials && !isUserCreatedCredential) {
if (null != peerCredentials && !isUserCreatedCredential && !useDefaultNativeGSSCredential) {
peerCredentials.dispose();
} else if (null != peerCredentials && isUserCreatedCredential) {
} else if (null != peerCredentials && (isUserCreatedCredential || useDefaultNativeGSSCredential)) {
peerCredentials = null;
}
if (null != peerContext) {
Expand Down
28 changes: 12 additions & 16 deletions src/main/java/com/microsoft/sqlserver/jdbc/SQLServerBulkCopy.java
Original file line number Diff line number Diff line change
Expand Up @@ -1729,40 +1729,36 @@ private void getDestinationMetadata() throws SQLServerException {
if (null != destinationTableMetadata) {
rs = (SQLServerResultSet) destinationTableMetadata;
} else {
stmt = (SQLServerStatement) connection.createStatement(ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY, connection.getHoldability(), stmtColumnEncriptionSetting);
stmt = (SQLServerStatement) connection.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, connection.getHoldability(), stmtColumnEncriptionSetting);

// Get destination metadata
rs = stmt.executeQueryInternal(
"sp_executesql N'SET FMTONLY ON SELECT * FROM " + escapedDestinationTableName + " '");
rs = stmt.executeQueryInternal("sp_executesql N'SET FMTONLY ON SELECT * FROM " + escapedDestinationTableName + " '");
}

destColumnCount = rs.getMetaData().getColumnCount();
int destColumnMetadataCount = rs.getMetaData().getColumnCount();
destColumnMetadata = new HashMap<>();
destCekTable = rs.getCekTable();

if (!connection.getServerSupportsColumnEncryption()) {
metaDataQuery = "select collation_name from sys.columns where " + "object_id=OBJECT_ID('"
+ escapedDestinationTableName + "') " + "order by column_id ASC";
} else {
metaDataQuery = "select collation_name, encryption_type from sys.columns where "
+ "object_id=OBJECT_ID('" + escapedDestinationTableName + "') " + "order by column_id ASC";
}
metaDataQuery = "select * from sys.columns where " + "object_id=OBJECT_ID('" + escapedDestinationTableName + "') " + "order by column_id ASC";

try (SQLServerStatement statementMoreMetadata = (SQLServerStatement) connection.createStatement();
SQLServerResultSet rsMoreMetaData = statementMoreMetadata.executeQueryInternal(metaDataQuery)) {
for (int i = 1; i <= destColumnCount; ++i) {
SQLServerResultSet rsMoreMetaData = statementMoreMetadata.executeQueryInternal(metaDataQuery)) {
for (int i = 1; i <= destColumnMetadataCount; ++i) {
if (rsMoreMetaData.next()) {
String bulkCopyEncryptionType = null;
if (connection.getServerSupportsColumnEncryption()) {
bulkCopyEncryptionType = rsMoreMetaData.getString("encryption_type");
}
destColumnMetadata.put(i, new BulkColumnMetaData(rs.getColumn(i),
rsMoreMetaData.getString("collation_name"), bulkCopyEncryptionType));
// Skip computed columns
if (!rsMoreMetaData.getBoolean("is_computed")) {
destColumnMetadata.put(i, new BulkColumnMetaData(rs.getColumn(i), rsMoreMetaData.getString("collation_name"),
bulkCopyEncryptionType));
}
} else {
destColumnMetadata.put(i, new BulkColumnMetaData(rs.getColumn(i)));
}
}
destColumnCount = destColumnMetadata.size();
}
} catch (SQLException e) {
// Unable to retrieve metadata for destination
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ public final class SQLServerColumnEncryptionCertificateStoreProvider extends SQL
static final private java.util.logging.Logger windowsCertificateStoreLogger = java.util.logging.Logger
.getLogger("com.microsoft.sqlserver.jdbc.SQLServerColumnEncryptionCertificateStoreProvider");

static boolean isWindows;

String name = "MSSQL_CERTIFICATE_STORE";

static final String LOCAL_MACHINE_DIRECTORY = "LocalMachine";
Expand All @@ -29,14 +27,6 @@ public final class SQLServerColumnEncryptionCertificateStoreProvider extends SQL

private static final Lock lock = new ReentrantLock();

static {
if (System.getProperty("os.name").toLowerCase(Locale.ENGLISH).startsWith("windows")) {
isWindows = true;
} else {
isWindows = false;
}
}

/**
* Constructs a SQLServerColumnEncryptionCertificateStoreProvider.
*/
Expand Down Expand Up @@ -67,7 +57,7 @@ public byte[] decryptColumnEncryptionKey(String masterKeyPath, String encryption
windowsCertificateStoreLogger.entering(SQLServerColumnEncryptionCertificateStoreProvider.class.getName(),
"decryptColumnEncryptionKey", "Decrypting Column Encryption Key.");
byte[] plainCek;
if (isWindows) {
if (SQLServerConnection.isWindows) {
plainCek = decryptColumnEncryptionKeyWindows(masterKeyPath, encryptionAlgorithm,
encryptedColumnEncryptionKey);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -996,8 +996,10 @@ IdleConnectionResiliency getSessionRecovery() {
/** global system ColumnEncryptionKeyStoreProviders */
static Map<String, SQLServerColumnEncryptionKeyStoreProvider> globalSystemColumnEncryptionKeyStoreProviders = new HashMap<>();

static boolean isWindows = System.getProperty("os.name").toLowerCase(Locale.ENGLISH).startsWith("windows");

static {
if (System.getProperty("os.name").toLowerCase(Locale.ENGLISH).startsWith("windows")) {
if (isWindows) {
SQLServerColumnEncryptionCertificateStoreProvider provider = new SQLServerColumnEncryptionCertificateStoreProvider();
globalSystemColumnEncryptionKeyStoreProviders.put(provider.getName(), provider);
}
Expand Down Expand Up @@ -1439,6 +1441,9 @@ public static void clearUserTokenCache() {
/** integrated authentication scheme */
private AuthenticationScheme intAuthScheme = AuthenticationScheme.NATIVE_AUTHENTICATION;

/** use default native GSS-API Credential flag */
private boolean useDefaultGSSCredential = SQLServerDriverBooleanProperty.USE_DEFAULT_GSS_CREDENTIAL.getDefaultValue();

/** impersonated user credential */
private transient GSSCredential impersonatedUserCred;

Expand Down Expand Up @@ -2493,6 +2498,11 @@ Connection connectInternal(Properties propsIn,
impersonatedUserCred = (GSSCredential) activeConnectionProperties.get(sPropKey);
isUserCreatedCredential = true;
}
sPropKey = SQLServerDriverBooleanProperty.USE_DEFAULT_GSS_CREDENTIAL.toString();
sPropValue = activeConnectionProperties.getProperty(sPropKey);
if(null != sPropValue && isWindows) {
useDefaultGSSCredential = isBooleanPropertyOn(sPropKey, sPropValue);
}
} else if (intAuthScheme == AuthenticationScheme.NTLM) {
String sPropKeyDomain = SQLServerDriverStringProperty.DOMAIN.toString();
String sPropValueDomain = activeConnectionProperties.getProperty(sPropKeyDomain);
Expand Down Expand Up @@ -5118,9 +5128,9 @@ private void logon(LogonCommand command) throws SQLServerException {
authentication = new AuthenticationJNI(this, currentConnectPlaceHolder.getServerName(),
currentConnectPlaceHolder.getPortNumber());
} else if (AuthenticationScheme.JAVA_KERBEROS == intAuthScheme) {
if (null != impersonatedUserCred) {
if (null != impersonatedUserCred || useDefaultGSSCredential) {
authentication = new KerbAuthentication(this, currentConnectPlaceHolder.getServerName(),
currentConnectPlaceHolder.getPortNumber(), impersonatedUserCred, isUserCreatedCredential);
currentConnectPlaceHolder.getPortNumber(), impersonatedUserCred, isUserCreatedCredential, useDefaultGSSCredential);
} else {
authentication = new KerbAuthentication(this, currentConnectPlaceHolder.getServerName(),
currentConnectPlaceHolder.getPortNumber());
Expand Down Expand Up @@ -5821,8 +5831,7 @@ private SqlAuthenticationToken getFedAuthToken(SqlFedAuthInfo fedAuthInfo) throw
} else if (authenticationString
.equalsIgnoreCase(SqlAuthentication.ACTIVE_DIRECTORY_INTEGRATED.toString())) {
// If operating system is windows and mssql-jdbc_auth is loaded then choose the DLL authentication.
if (System.getProperty("os.name").toLowerCase(Locale.ENGLISH).startsWith("windows")
&& AuthenticationJNI.isDllLoaded()) {
if (isWindows && AuthenticationJNI.isDllLoaded()) {
try {
FedAuthDllInfo dllInfo = AuthenticationJNI.getAccessTokenForWindowsIntegrated(
fedAuthInfo.stsurl, fedAuthInfo.spn, clientConnectionId.toString(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,17 @@ public GSSCredential getGSSCredentials() {
SQLServerDriverObjectProperty.GSS_CREDENTIAL.getDefaultValue());
}

@Override
public void setUseDefaultGSSCredential(boolean enable) {
setBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.USE_DEFAULT_GSS_CREDENTIAL.toString(), enable);
}

@Override
public boolean getUseDefaultGSSCredential() {
return getBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.USE_DEFAULT_GSS_CREDENTIAL.toString(),
SQLServerDriverBooleanProperty.USE_DEFAULT_GSS_CREDENTIAL.getDefaultValue());
}

@Override
public void setAccessToken(String accessToken) {
setStringProperty(connectionProps, SQLServerDriverStringProperty.ACCESS_TOKEN.toString(), accessToken);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -695,7 +695,8 @@ enum SQLServerDriverBooleanProperty {
SEND_TEMPORAL_DATATYPES_AS_STRING_FOR_BULK_COPY("sendTemporalDataTypesAsStringForBulkCopy", true),
DELAY_LOADING_LOBS("delayLoadingLobs", true),
IGNORE_OFFSET_ON_DATE_TIME_OFFSET_CONVERSION("ignoreOffsetOnDateTimeOffsetConversion", false),
USE_DEFAULT_JAAS_CONFIG("useDefaultJaasConfig", false);
USE_DEFAULT_JAAS_CONFIG("useDefaultJaasConfig", false),
USE_DEFAULT_GSS_CREDENTIAL("useDefaultGSSCredential", false);

private final String name;
private final boolean defaultValue;
Expand Down Expand Up @@ -749,7 +750,7 @@ public final class SQLServerDriver implements java.sql.Driver {
SQLServerDriverStringProperty.DATABASE_NAME.getDefaultValue(), false, null),
new SQLServerDriverPropertyInfo(SQLServerDriverBooleanProperty.DISABLE_STATEMENT_POOLING.toString(),
Boolean.toString(SQLServerDriverBooleanProperty.DISABLE_STATEMENT_POOLING.getDefaultValue()), false,
new String[] {"true", "false"}),
TRUE_FALSE),
new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.ENCRYPT.toString(),
SQLServerDriverStringProperty.ENCRYPT.getDefaultValue(), false,
new String[] {EncryptOption.FALSE.toString(), EncryptOption.NO.toString(),
Expand All @@ -769,6 +770,9 @@ public final class SQLServerDriver implements java.sql.Driver {
new SQLServerDriverPropertyInfo(SQLServerDriverBooleanProperty.INTEGRATED_SECURITY.toString(),
Boolean.toString(SQLServerDriverBooleanProperty.INTEGRATED_SECURITY.getDefaultValue()), false,
TRUE_FALSE),
new SQLServerDriverPropertyInfo(SQLServerDriverBooleanProperty.USE_DEFAULT_GSS_CREDENTIAL.toString(),
Boolean.toString(SQLServerDriverBooleanProperty.USE_DEFAULT_GSS_CREDENTIAL.getDefaultValue()), false,
TRUE_FALSE),
new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.KEY_STORE_AUTHENTICATION.toString(),
SQLServerDriverStringProperty.KEY_STORE_AUTHENTICATION.getDefaultValue(), false,
new String[] {KeyStoreAuthentication.JAVA_KEYSTORE_PASSWORD.toString()}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2142,6 +2142,9 @@ public int[] executeBatch() throws SQLServerException, BatchUpdateException, SQL
CryptoMetadata cryptoMetadata = c.getCryptoMetadata();
int jdbctype;
TypeInfo ti = c.getTypeInfo();
if (ti.getUpdatability() == 0) { // Skip read only columns
continue;
}
checkValidColumns(ti);
if (null != cryptoMetadata) {
jdbctype = cryptoMetadata.getBaseTypeInfo().getSSType().getJDBCType().getIntValue();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ protected Object[][] getContents() {
{"R_lastUpdateCountPropertyDescription", "Ensures that only the last update count is returned from an SQL statement passed to the server."},
{"R_disableStatementPoolingPropertyDescription", "Disables the statement pooling feature."},
{"R_integratedSecurityPropertyDescription", "Indicates whether Windows authentication will be used to connect to SQL Server."},
{"R_useDefaultGSSCredentialPropertyDescription", "Indicates whether GSSCredential will be created using native GSS-API."},
{"R_authenticationSchemePropertyDescription", "The authentication scheme to be used for integrated authentication."},
{"R_lockTimeoutPropertyDescription", "The number of milliseconds to wait before the database reports a lock time-out."},
{"R_connectRetryCountPropertyDescription", "The number of reconnection attempts if there is a connection failure."},
Expand Down
Loading

0 comments on commit 04d7b85

Please sign in to comment.