postgresql-jdbc.git / summary / log / commit / refs
commit 187b90681dbceddea2cbffded9dcdc4bf95ddacb
Author: Nick Hall <github@nickh.net>
Commit: GitHub <noreply@github.com>
Date: Fri Nov 22 17:36:12 2024 +0000
Support default GSS credentials in the Java Postgres client (#3451)
* support default GSSAPI credentials
* fix unexpected line deletion
* fix ordering of new property
docs/content/documentation/use.md | 5 +++++
pgjdbc/src/main/java/org/postgresql/PGProperty.java | 13 +++++++++++++
.../org/postgresql/core/v3/ConnectionFactoryImpl.java | 2 ++
.../java/org/postgresql/ds/common/BaseDataSource.java | 16 ++++++++++++++++
pgjdbc/src/main/java/org/postgresql/gss/GssAction.java | 15 +++++++++++----
.../src/main/java/org/postgresql/gss/GssEncAction.java | 15 +++++++++++----
pgjdbc/src/main/java/org/postgresql/gss/MakeGSS.java | 6 +++---
7 files changed, 61 insertions(+), 11 deletions(-)
diff --git a/docs/content/documentation/use.md b/docs/content/documentation/use.md
index ae08e934..17f4cf82 100644
--- a/docs/content/documentation/use.md
+++ b/docs/content/documentation/use.md
@@ -293,6 +293,11 @@ Specifies whether to perform a JAAS login before authenticating with GSSAPI.
If set to `true` (the default), the driver will attempt to obtain GSS credentials using the configured JAAS login module(s) (e.g. `Krb5LoginModule` ) before authenticating.
To skip the JAAS login, for example if the native GSS implementation is being used to obtain credentials, set this to `false` .
+* **`gssUseDefaultCreds (`*boolean*`)`** *Default `false`*\
+Specifies whether to use the default system GSS credentials, rather than using JAAS.
+If set to `false` (the default), the driver will attempt to use GSS credentials matching `user`@DEFAULT_REALM. If true, the
+driver will use the default system GSS credentials. This is useful in cases where the default credentials are named differently,
+or CCACHE sources like KCM are used, which JAAS does not support on all platforms.
* **`gssEncMode (`*String*`)`** *Default `allow`*\
PostgreSQLĀ® 12 and later now allow GSSAPI encrypted connections. This parameter controls whether to enforce using GSSAPI encryption or not. The options are `disable` , `allow` , `prefer` and `require`
* `disable` is obvious and disables any attempt to connect using GSS encrypted mode
diff --git a/pgjdbc/src/main/java/org/postgresql/PGProperty.java b/pgjdbc/src/main/java/org/postgresql/PGProperty.java
index 2d507e83..5a5a3cca 100644
--- a/pgjdbc/src/main/java/org/postgresql/PGProperty.java
+++ b/pgjdbc/src/main/java/org/postgresql/PGProperty.java
@@ -285,6 +285,19 @@ public enum PGProperty {
"5000",
"Time in milliseconds we wait for a response from the server after requesting a GSS upgrade"),
+ /**
+ * Flag to enable/disable the obtaining the default GSS credentials from a pre-existing ccache,
+ * rather than using JAAS. This also allows GSS to work in environments where the default
+ * kerberos principal a user has is not user@DEFAULT_REALM, but some other user (this is valid,
+ * and often the case in more advanced Kerberos setups). Finally, this also means that if
+ * the "native" GSS implementation is used (i.e. the local system GSS libraries), all means of
+ * fetching the default credential are supported. Currently, JAAS is pure java on Linux, and
+ * does not support the use of KCM (and only supports file-based ccaches and keytabs).
+ */
+ GSS_USE_DEFAULT_CREDS(
+ "gssUseDefaultCreds",
+ "false",
+ "Use the default GSS credentials the process already has, rather than a JAAS login"),
/**
* Enable mode to filter out the names of database objects for which the current user has no privileges
diff --git a/pgjdbc/src/main/java/org/postgresql/core/v3/ConnectionFactoryImpl.java b/pgjdbc/src/main/java/org/postgresql/core/v3/ConnectionFactoryImpl.java
index a0bfb6c0..cfb28e50 100644
--- a/pgjdbc/src/main/java/org/postgresql/core/v3/ConnectionFactoryImpl.java
+++ b/pgjdbc/src/main/java/org/postgresql/core/v3/ConnectionFactoryImpl.java
@@ -553,6 +553,7 @@ public class ConnectionFactoryImpl extends ConnectionFactory {
PGProperty.JAAS_APPLICATION_NAME.getOrDefault(info),
PGProperty.KERBEROS_SERVER_NAME.getOrDefault(info), false, // TODO: fix this
PGProperty.JAAS_LOGIN.getBoolean(info),
+ PGProperty.GSS_USE_DEFAULT_CREDS.getBoolean(info),
PGProperty.LOG_SERVER_ERROR_DETAIL.getBoolean(info));
return void.class;
});
@@ -838,6 +839,7 @@ public class ConnectionFactoryImpl extends ConnectionFactory {
PGProperty.JAAS_APPLICATION_NAME.getOrDefault(info),
PGProperty.KERBEROS_SERVER_NAME.getOrDefault(info), usespnego,
PGProperty.JAAS_LOGIN.getBoolean(info),
+ PGProperty.GSS_USE_DEFAULT_CREDS.getBoolean(info),
PGProperty.LOG_SERVER_ERROR_DETAIL.getBoolean(info));
return void.class;
});
diff --git a/pgjdbc/src/main/java/org/postgresql/ds/common/BaseDataSource.java b/pgjdbc/src/main/java/org/postgresql/ds/common/BaseDataSource.java
index ce3df39d..544d2c74 100644
--- a/pgjdbc/src/main/java/org/postgresql/ds/common/BaseDataSource.java
+++ b/pgjdbc/src/main/java/org/postgresql/ds/common/BaseDataSource.java
@@ -1138,6 +1138,22 @@ public abstract class BaseDataSource implements CommonDataSource, Referenceable
PGProperty.JAAS_LOGIN.set(properties, doLogin);
}
+ /**
+ * @return true if using default GSS credentials
+ * @see PGProperty#GSS_USE_DEFAULT_CREDS
+ */
+ public boolean getGssUseDefaultCreds() {
+ return PGProperty.GSS_USE_DEFAULT_CREDS.getBoolean(properties);
+ }
+
+ /**
+ * @param gssUseDefaultCreds true if using default GSS credentials
+ * @see PGProperty#GSS_USE_DEFAULT_CREDS
+ */
+ public void setGssUseDefaultCreds(boolean gssUseDefaultCreds) {
+ PGProperty.GSS_USE_DEFAULT_CREDS.set(properties, gssUseDefaultCreds);
+ }
+
/**
* @return Kerberos server name
* @see PGProperty#KERBEROS_SERVER_NAME
diff --git a/pgjdbc/src/main/java/org/postgresql/gss/GssAction.java b/pgjdbc/src/main/java/org/postgresql/gss/GssAction.java
index 358aac92..9ba472f1 100644
--- a/pgjdbc/src/main/java/org/postgresql/gss/GssAction.java
+++ b/pgjdbc/src/main/java/org/postgresql/gss/GssAction.java
@@ -38,17 +38,20 @@ class GssAction implements PrivilegedAction<@Nullable Exception>, Callable<@Null
private final String kerberosServerName;
private final String user;
private final boolean useSpnego;
+ private final boolean gssUseDefaultCreds;
private final @Nullable Subject subject;
private final boolean logServerErrorDetail;
GssAction(PGStream pgStream, @Nullable Subject subject, String host, String user,
- String kerberosServerName, boolean useSpnego, boolean logServerErrorDetail) {
+ String kerberosServerName, boolean useSpnego, boolean gssUseDefaultCreds,
+ boolean logServerErrorDetail) {
this.pgStream = pgStream;
this.subject = subject;
this.host = host;
this.user = user;
this.kerberosServerName = kerberosServerName;
this.useSpnego = useSpnego;
+ this.gssUseDefaultCreds = gssUseDefaultCreds;
this.logServerErrorDetail = logServerErrorDetail;
}
@@ -101,9 +104,13 @@ class GssAction implements PrivilegedAction<@Nullable Exception>, Callable<@Null
}
}
- GSSName clientName = manager.createName(principalName, GSSName.NT_USER_NAME);
- clientCreds = manager.createCredential(clientName, 8 * 3600, desiredMechs,
- GSSCredential.INITIATE_ONLY);
+ if (gssUseDefaultCreds) {
+ clientCreds = manager.createCredential(GSSCredential.INITIATE_ONLY);
+ } else {
+ GSSName clientName = manager.createName(principalName, GSSName.NT_USER_NAME);
+ clientCreds = manager.createCredential(clientName, 8 * 3600, desiredMechs,
+ GSSCredential.INITIATE_ONLY);
+ }
} else {
desiredMechs[0] = new Oid("1.2.840.113554.1.2.2");
clientCreds = gssCredential;
diff --git a/pgjdbc/src/main/java/org/postgresql/gss/GssEncAction.java b/pgjdbc/src/main/java/org/postgresql/gss/GssEncAction.java
index 7672654b..65eae333 100644
--- a/pgjdbc/src/main/java/org/postgresql/gss/GssEncAction.java
+++ b/pgjdbc/src/main/java/org/postgresql/gss/GssEncAction.java
@@ -36,18 +36,21 @@ public class GssEncAction implements PrivilegedAction<@Nullable Exception>, Call
private final String user;
private final String kerberosServerName;
private final boolean useSpnego;
+ private final boolean gssUseDefaultCreds;
private final @Nullable Subject subject;
private final boolean logServerErrorDetail;
public GssEncAction(PGStream pgStream, @Nullable Subject subject,
String host, String user,
- String kerberosServerName, boolean useSpnego, boolean logServerErrorDetail) {
+ String kerberosServerName, boolean useSpnego, boolean gssUseDefaultCreds,
+ boolean logServerErrorDetail) {
this.pgStream = pgStream;
this.subject = subject;
this.host = host;
this.user = user;
this.kerberosServerName = kerberosServerName;
this.useSpnego = useSpnego;
+ this.gssUseDefaultCreds = gssUseDefaultCreds;
this.logServerErrorDetail = logServerErrorDetail;
}
@@ -100,9 +103,13 @@ public class GssEncAction implements PrivilegedAction<@Nullable Exception>, Call
}
}
- GSSName clientName = manager.createName(principalName, GSSName.NT_USER_NAME);
- clientCreds = manager.createCredential(clientName, 8 * 3600, desiredMechs,
- GSSCredential.INITIATE_ONLY);
+ if (gssUseDefaultCreds) {
+ clientCreds = manager.createCredential(GSSCredential.INITIATE_ONLY);
+ } else {
+ GSSName clientName = manager.createName(principalName, GSSName.NT_USER_NAME);
+ clientCreds = manager.createCredential(clientName, 8 * 3600, desiredMechs,
+ GSSCredential.INITIATE_ONLY);
+ }
} else {
desiredMechs[0] = new Oid("1.2.840.113554.1.2.2");
clientCreds = gssCredential;
diff --git a/pgjdbc/src/main/java/org/postgresql/gss/MakeGSS.java b/pgjdbc/src/main/java/org/postgresql/gss/MakeGSS.java
index 19c61461..1f482a99 100644
--- a/pgjdbc/src/main/java/org/postgresql/gss/MakeGSS.java
+++ b/pgjdbc/src/main/java/org/postgresql/gss/MakeGSS.java
@@ -118,7 +118,7 @@ public class MakeGSS {
public static void authenticate(boolean encrypted,
PGStream pgStream, String host, String user, char @Nullable [] password,
@Nullable String jaasApplicationName, @Nullable String kerberosServerName,
- boolean useSpnego, boolean jaasLogin,
+ boolean useSpnego, boolean jaasLogin, boolean gssUseDefaultCreds,
boolean logServerErrorDetail)
throws IOException, PSQLException {
LOGGER.log(Level.FINEST, " <=BE AuthenticationReqGSS");
@@ -151,10 +151,10 @@ public class MakeGSS {
PrivilegedAction<@Nullable Exception> action;
if ( encrypted ) {
action = new GssEncAction(pgStream, sub, host, user,
- kerberosServerName, useSpnego, logServerErrorDetail);
+ kerberosServerName, useSpnego, gssUseDefaultCreds, logServerErrorDetail);
} else {
action = new GssAction(pgStream, sub, host, user,
- kerberosServerName, useSpnego, logServerErrorDetail);
+ kerberosServerName, useSpnego, gssUseDefaultCreds, logServerErrorDetail);
}
//noinspection ConstantConditions
@SuppressWarnings({"cast.unsafe", "assignment"})
[parent: 180459fa296b]