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

Kerberos Constrained Delegation Impersonated Credential Expiry fix #636

Merged
merged 11 commits into from
May 31, 2018
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>3.4.0</version>
<version>3.5.0</version>
<extensions>true</extensions>
<configuration>
<instructions>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -388,9 +389,10 @@ interface RealmValidator {
KerbAuthentication(SQLServerConnection con,
String address,
int port,
GSSCredential ImpersonatedUserCred) throws SQLServerException {
GSSCredential ImpersonatedUserCred, Boolean isUserCreated) throws SQLServerException {
this(con, address, port);
peerCredentials = ImpersonatedUserCred;
this.isUserCreatedCredential = (isUserCreated == null ? false : isUserCreated);
}

byte[] GenerateClientContext(byte[] pin,
Expand All @@ -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)
Expand Down
30 changes: 13 additions & 17 deletions src/main/java/com/microsoft/sqlserver/jdbc/SQLServerConnection.java
Original file line number Diff line number Diff line change
Expand Up @@ -753,7 +753,8 @@ static synchronized List<String> 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;

Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -3435,9 +3438,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);
ImpersonatedUserCred, isUserCreatedCredential);
}
else
authentication = new KerbAuthentication(this, currentConnectPlaceHolder.getServerName(), currentConnectPlaceHolder.getPortNumber());
}
Expand All @@ -3459,7 +3463,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);

Expand All @@ -3473,21 +3476,14 @@ final boolean doExecute() throws SQLServerException {
connectionCommand(sqlStmt, "Change Settings");
}
}
}
finally {
} finally {
if (integratedSecurity) {
if (null != authentication)
if (null != authentication) {
authentication.ReleaseClientContext();
authentication = null;

authentication = null;
}
if (null != ImpersonatedUserCred) {
try {
ImpersonatedUserCred.dispose();
}
catch (GSSException e) {
if (connectionlogger.isLoggable(Level.FINER))
connectionlogger.finer(toString() + " Release of the credentials failed GSSException: " + e);
}
ImpersonatedUserCred = null;
}
}
}
Expand Down