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

feat: WIP Filter DatabaseMetaData using privileges for the user #1630

Merged
merged 2 commits into from Dec 5, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 7 additions & 0 deletions pgjdbc/src/main/java/org/postgresql/PGProperty.java
Expand Up @@ -425,6 +425,13 @@ public enum PGProperty {
REWRITE_BATCHED_INSERTS("reWriteBatchedInserts", "false",
"Enable optimization to rewrite and collapse compatible INSERT statements that are batched."),

/**
* Enable mode to filter out the names of database objects for which the current user has no privileges
* granted from appearing in the DatabaseMetaData returned by the driver.
*/
HIDE_UNPRIVILEGED_OBJECTS("hideUnprivilegedObjects", "false",
"Enable hiding of database objects for which the current user has no privileges granted from the DatabaseMetaData"),

/**
* <p>Connection parameter passed in the startup message. This parameter accepts two values; "true"
* and "database". Passing "true" tells the backend to go into walsender mode, wherein a small set
Expand Down
16 changes: 16 additions & 0 deletions pgjdbc/src/main/java/org/postgresql/ds/common/BaseDataSource.java
Expand Up @@ -1495,6 +1495,22 @@ public void setReWriteBatchedInserts(boolean reWrite) {
PGProperty.REWRITE_BATCHED_INSERTS.set(properties, reWrite);
}

/**
* @return boolean indicating property is enabled or not.
* @see PGProperty#HIDE_UNPRIVILEGED_OBJECTS
*/
public boolean getHideUnprivilegedObjects() {
return PGProperty.HIDE_UNPRIVILEGED_OBJECTS.getBoolean(properties);
}

/**
* @param hideUnprivileged boolean value to set the property in the properties collection
* @see PGProperty#HIDE_UNPRIVILEGED_OBJECTS
*/
public void setHideUnprivilegedObjects(boolean hideUnprivileged) {
PGProperty.HIDE_UNPRIVILEGED_OBJECTS.set(properties, hideUnprivileged);
}

//#if mvn.project.property.postgresql.jdbc.spec >= "JDBC4.1"
public java.util.logging.Logger getParentLogger() {
return Logger.getLogger("org.postgresql");
Expand Down
9 changes: 8 additions & 1 deletion pgjdbc/src/main/java/org/postgresql/jdbc/PgConnection.java
Expand Up @@ -134,7 +134,8 @@ private enum ReadOnlyBehavior {
private boolean autoCommit = true;
// Connection's readonly state.
private boolean readOnly = false;

// Filter out database objects for which the current user has no privileges granted from the DatabaseMetaData
private boolean hideUnprivilegedObjects ;
// Bind String to UNSPECIFIED or VARCHAR?
private final boolean bindStringAsVarchar;

Expand Down Expand Up @@ -221,6 +222,8 @@ public PgConnection(HostSpec[] hostSpecs,
setReadOnly(true);
}

this.hideUnprivilegedObjects = PGProperty.HIDE_UNPRIVILEGED_OBJECTS.getBoolean(info);

Set<Integer> binaryOids = getBinaryOids(info);

// split for receive and send for better control
Expand Down Expand Up @@ -948,6 +951,10 @@ public String getCatalog() throws SQLException {
return queryExecutor.getDatabase();
}

public boolean getHideUnprivilegedObjects() {
return hideUnprivilegedObjects;
}

/**
* <p>Overrides finalize(). If called, it closes the connection.</p>
*
Expand Down
23 changes: 23 additions & 0 deletions pgjdbc/src/main/java/org/postgresql/jdbc/PgDatabaseMetaData.java
Expand Up @@ -1045,6 +1045,9 @@ public ResultSet getProcedures(String catalog, String schemaPattern, String proc
if (procedureNamePattern != null && !procedureNamePattern.isEmpty()) {
sql += " AND p.proname LIKE " + escapeQuotes(procedureNamePattern);
}
if (connection.getHideUnprivilegedObjects()) {
sql += " AND has_function_privilege(p.oid,'EXECUTE')";
}
sql += " ORDER BY PROCEDURE_SCHEM, PROCEDURE_NAME, p.oid::text ";

return createMetaDataStatement().executeQuery(sql);
Expand Down Expand Up @@ -1303,6 +1306,10 @@ public ResultSet getTables(String catalog, String schemaPattern, String tableNam
if (schemaPattern != null && !schemaPattern.isEmpty()) {
select += " AND n.nspname LIKE " + escapeQuotes(schemaPattern);
}
if (connection.getHideUnprivilegedObjects()) {
select += " AND has_table_privilege(c.oid, "
+ " 'SELECT, INSERT, UPDATE, DELETE, RULE, REFERENCES, TRIGGER')";
}
orderby = " ORDER BY TABLE_TYPE,TABLE_SCHEM,TABLE_NAME ";

if (tableNamePattern != null && !tableNamePattern.isEmpty()) {
Expand Down Expand Up @@ -1419,6 +1426,9 @@ public ResultSet getSchemas(String catalog, String schemaPattern) throws SQLExce
if (schemaPattern != null && !schemaPattern.isEmpty()) {
sql += " AND nspname LIKE " + escapeQuotes(schemaPattern);
}
if (connection.getHideUnprivilegedObjects()) {
sql += " AND has_schema_privilege(nspname, 'USAGE, CREATE')";
}
sql += " ORDER BY TABLE_SCHEM";

return createMetaDataStatement().executeQuery(sql);
Expand Down Expand Up @@ -2266,6 +2276,10 @@ public ResultSet getTypeInfo() throws SQLException {
+ " AND "
+ " (t.typrelid = 0 OR (SELECT c.relkind = 'c' FROM pg_catalog.pg_class c WHERE c.oid = t.typrelid))";

if (connection.getHideUnprivilegedObjects() && connection.haveMinimumServerVersion(ServerVersion.v9_2)) {
sql += " AND has_type_privilege(t.oid, 'USAGE')";
}

Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery(sql);
// cache some results, this will keep memory usage down, and speed
Expand Down Expand Up @@ -2584,6 +2598,12 @@ public ResultSet getUDTs(String catalog, String schemaPattern, String typeNamePa
toAdd.append(" and n.nspname like ").append(escapeQuotes(schemaPattern));
}
sql += toAdd.toString();

if (connection.getHideUnprivilegedObjects()
&& connection.haveMinimumServerVersion(ServerVersion.v9_2)) {
sql += " AND has_type_privilege(t.oid, 'USAGE')";
}

sql += " order by data_type, type_schem, type_name";
return createMetaDataStatement().executeQuery(sql);
}
Expand Down Expand Up @@ -2695,6 +2715,9 @@ public ResultSet getFunctions(String catalog, String schemaPattern, String funct
if (functionNamePattern != null && !functionNamePattern.isEmpty()) {
sql += " AND p.proname LIKE " + escapeQuotes(functionNamePattern);
}
if (connection.getHideUnprivilegedObjects()) {
sql += " AND has_function_privilege(p.oid,'EXECUTE')";
}
sql += " ORDER BY FUNCTION_SCHEM, FUNCTION_NAME, p.oid::text ";

return createMetaDataStatement().executeQuery(sql);
Expand Down