From dc68b14aa1f58f78f09a262b76c4d5f14d2b6d65 Mon Sep 17 00:00:00 2001 From: rene-ye Date: Thu, 8 Feb 2018 11:13:37 -0800 Subject: [PATCH 1/6] Kerberos DC fix for automatic credential discarding --- .../sqlserver/jdbc/SQLServerConnection.java | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerConnection.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerConnection.java index c8232d71a..6b5fc59ea 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerConnection.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerConnection.java @@ -3428,19 +3428,24 @@ final boolean doExecute() throws SQLServerException { } } finally { - if (integratedSecurity) { - if (null != authentication) - authentication.ReleaseClientContext(); - authentication = null; - + if (integratedSecurity) { if (null != ImpersonatedUserCred) { try { - ImpersonatedUserCred.dispose(); + if (ImpersonatedUserCred.getRemainingLifetime() <= 0) { + if (null != authentication) + authentication.ReleaseClientContext(); + authentication = null; + ImpersonatedUserCred.dispose(); + } } catch (GSSException e) { if (connectionlogger.isLoggable(Level.FINER)) connectionlogger.finer(toString() + " Release of the credentials failed GSSException: " + e); } + } else { + if (null != authentication) + authentication.ReleaseClientContext(); + authentication = null; } } } From f4bf4ed7cd5a9d719269165aa0575c51c2a2bc9a Mon Sep 17 00:00:00 2001 From: rene-ye Date: Tue, 1 May 2018 14:56:08 -0700 Subject: [PATCH 2/6] formatting fixes --- .../microsoft/sqlserver/jdbc/SQLServerConnection.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerConnection.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerConnection.java index 587ffb75e..39c108ec5 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerConnection.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerConnection.java @@ -3423,11 +3423,12 @@ final boolean doExecute() throws SQLServerException { if (integratedSecurity) { if (null != ImpersonatedUserCred) { try { - if (ImpersonatedUserCred.getRemainingLifetime() <= 0) { - if (null != authentication) + if (ImpersonatedUserCred.getRemainingLifetime() <= 0) { + if (null != authentication) { authentication.ReleaseClientContext(); + } authentication = null; - ImpersonatedUserCred.dispose(); + ImpersonatedUserCred.dispose(); } } catch (GSSException e) { @@ -3435,8 +3436,9 @@ final boolean doExecute() throws SQLServerException { connectionlogger.finer(toString() + " Release of the credentials failed GSSException: " + e); } } else { - if (null != authentication) + if (null != authentication) { authentication.ReleaseClientContext(); + } authentication = null; } } From d969b0340b61b5fe42ba59e6d231a1a8fe95b8d5 Mon Sep 17 00:00:00 2001 From: rene-ye Date: Tue, 29 May 2018 12:01:36 -0700 Subject: [PATCH 3/6] update felix to 3.5.0 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f1f5dd160..2a882c77a 100644 --- a/pom.xml +++ b/pom.xml @@ -259,7 +259,7 @@ org.apache.felix maven-bundle-plugin - 3.4.0 + 3.5.0 true From 88dc78bf4fb2e557a5910e49ca1df2f481cb5b3f Mon Sep 17 00:00:00 2001 From: rene-ye Date: Wed, 30 May 2018 16:26:28 -0700 Subject: [PATCH 4/6] Revised implementation Decided to not dispose user created credentials at all. --- .../sqlserver/jdbc/KerbAuthentication.java | 7 +++- .../sqlserver/jdbc/SQLServerConnection.java | 32 ++++++------------- 2 files changed, 15 insertions(+), 24 deletions(-) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/KerbAuthentication.java b/src/main/java/com/microsoft/sqlserver/jdbc/KerbAuthentication.java index 01ace7365..72b803b27 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/KerbAuthentication.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/KerbAuthentication.java @@ -49,6 +49,7 @@ final class KerbAuthentication extends SSPIAuthentication { private final GSSManager manager = GSSManager.getInstance(); private LoginContext lc = null; + private boolean isUserCreatedCredential = false; private GSSCredential peerCredentials = null; private GSSContext peerContext = null; @@ -390,6 +391,7 @@ interface RealmValidator { int port, GSSCredential ImpersonatedUserCred) throws SQLServerException { this(con, address, port); + isUserCreatedCredential = true; peerCredentials = ImpersonatedUserCred; } @@ -403,8 +405,11 @@ byte[] GenerateClientContext(byte[] pin, int ReleaseClientContext() throws SQLServerException { try { - if (null != peerCredentials) + if (null != peerCredentials && !isUserCreatedCredential) { peerCredentials.dispose(); + } else if (null != peerCredentials && isUserCreatedCredential) { + peerCredentials = null; + } if (null != peerContext) peerContext.dispose(); if (null != lc) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerConnection.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerConnection.java index 36cf8ea2a..17175b0e7 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerConnection.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerConnection.java @@ -3417,9 +3417,10 @@ final boolean doExecute() throws SQLServerException { if (integratedSecurity && AuthenticationScheme.nativeAuthentication == intAuthScheme) authentication = new AuthenticationJNI(this, currentConnectPlaceHolder.getServerName(), currentConnectPlaceHolder.getPortNumber()); if (integratedSecurity && AuthenticationScheme.javaKerberos == intAuthScheme) { - if (null != ImpersonatedUserCred) + if (null != ImpersonatedUserCred) { authentication = new KerbAuthentication(this, currentConnectPlaceHolder.getServerName(), currentConnectPlaceHolder.getPortNumber(), ImpersonatedUserCred); + } else authentication = new KerbAuthentication(this, currentConnectPlaceHolder.getServerName(), currentConnectPlaceHolder.getPortNumber()); } @@ -3441,7 +3442,6 @@ final boolean doExecute() throws SQLServerException { // No need any further info from the server for token based authentication. So set _federatedAuthenticationRequested to true federatedAuthenticationRequested = true; } - try { sendLogon(command, authentication, fedAuthFeatureExtensionData); @@ -3455,29 +3455,15 @@ final boolean doExecute() throws SQLServerException { connectionCommand(sqlStmt, "Change Settings"); } } - } - finally { - if (integratedSecurity) { - if (null != ImpersonatedUserCred) { - try { - if (ImpersonatedUserCred.getRemainingLifetime() <= 0) { - if (null != authentication) { - authentication.ReleaseClientContext(); - } - authentication = null; - ImpersonatedUserCred.dispose(); - } - } - catch (GSSException e) { - if (connectionlogger.isLoggable(Level.FINER)) - connectionlogger.finer(toString() + " Release of the credentials failed GSSException: " + e); - } - } else { - if (null != authentication) { - authentication.ReleaseClientContext(); - } + } finally { + if (integratedSecurity) { + if (null != authentication) { + authentication.ReleaseClientContext(); authentication = null; } + if (null != ImpersonatedUserCred) { + ImpersonatedUserCred = null; + } } } } From ead01d30713efd1445aa2bb9fe039a9769d1619b Mon Sep 17 00:00:00 2001 From: rene-ye Date: Thu, 31 May 2018 09:54:32 -0700 Subject: [PATCH 5/6] Updated flag set location --- .../microsoft/sqlserver/jdbc/KerbAuthentication.java | 12 ++++++++++-- .../sqlserver/jdbc/SQLServerConnection.java | 9 ++++++--- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/KerbAuthentication.java b/src/main/java/com/microsoft/sqlserver/jdbc/KerbAuthentication.java index 72b803b27..80ba81529 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/KerbAuthentication.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/KerbAuthentication.java @@ -389,10 +389,18 @@ interface RealmValidator { KerbAuthentication(SQLServerConnection con, String address, int port, - GSSCredential ImpersonatedUserCred) throws SQLServerException { + GSSCredential ImpersonatedUserCred, Boolean isUserCreated) throws SQLServerException { this(con, address, port); - isUserCreatedCredential = true; peerCredentials = ImpersonatedUserCred; + this.isUserCreatedCredential = (isUserCreated == null ? false : isUserCreated); + } + + /** + * Sets the flag indicating whether we are using a user created credential. We should not dispose/change user created objects. + * @param b + */ + void setUserCreatedCredential(boolean b) { + this.isUserCreatedCredential = b; } byte[] GenerateClientContext(byte[] pin, diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerConnection.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerConnection.java index f80de8b16..ab7a758aa 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerConnection.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerConnection.java @@ -753,7 +753,8 @@ static synchronized List getColumnEncryptionTrustedMasterKeyPaths(String Properties activeConnectionProperties; // the active set of connection properties private boolean integratedSecurity = SQLServerDriverBooleanProperty.INTEGRATED_SECURITY.getDefaultValue(); private AuthenticationScheme intAuthScheme = AuthenticationScheme.nativeAuthentication; - private GSSCredential ImpersonatedUserCred ; + private GSSCredential ImpersonatedUserCred; + private Boolean isUserCreatedCredential; // This is the current connect place holder this should point one of the primary or failover place holder ServerPortPlaceHolder currentConnectPlaceHolder = null; @@ -1483,8 +1484,10 @@ Connection connectInternal(Properties propsIn, if(intAuthScheme == AuthenticationScheme.javaKerberos){ sPropKey = SQLServerDriverObjectProperty.GSS_CREDENTIAL.toString(); - if(activeConnectionProperties.containsKey(sPropKey)) + if(activeConnectionProperties.containsKey(sPropKey)) { ImpersonatedUserCred = (GSSCredential) activeConnectionProperties.get(sPropKey); + isUserCreatedCredential = true; + } } sPropKey = SQLServerDriverStringProperty.AUTHENTICATION.toString(); @@ -3437,7 +3440,7 @@ final boolean doExecute() throws SQLServerException { if (integratedSecurity && AuthenticationScheme.javaKerberos == intAuthScheme) { if (null != ImpersonatedUserCred) { authentication = new KerbAuthentication(this, currentConnectPlaceHolder.getServerName(), currentConnectPlaceHolder.getPortNumber(), - ImpersonatedUserCred); + ImpersonatedUserCred, isUserCreatedCredential); } else authentication = new KerbAuthentication(this, currentConnectPlaceHolder.getServerName(), currentConnectPlaceHolder.getPortNumber()); From 2c59e1dcd2f3500ec61c3ad65dbb84457c534756 Mon Sep 17 00:00:00 2001 From: rene-ye Date: Thu, 31 May 2018 09:58:10 -0700 Subject: [PATCH 6/6] remoed unncessary function --- .../com/microsoft/sqlserver/jdbc/KerbAuthentication.java | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/KerbAuthentication.java b/src/main/java/com/microsoft/sqlserver/jdbc/KerbAuthentication.java index 80ba81529..d3707c2fe 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/KerbAuthentication.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/KerbAuthentication.java @@ -394,14 +394,6 @@ interface RealmValidator { peerCredentials = ImpersonatedUserCred; this.isUserCreatedCredential = (isUserCreated == null ? false : isUserCreated); } - - /** - * Sets the flag indicating whether we are using a user created credential. We should not dispose/change user created objects. - * @param b - */ - void setUserCreatedCredential(boolean b) { - this.isUserCreatedCredential = b; - } byte[] GenerateClientContext(byte[] pin, boolean[] done) throws SQLServerException {