git.postgresql.org Git - postgresql.git/commitdiff

git projects / postgresql.git / commitdiff
? search:
summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: ff6c93b)
Fix column privilege checking for cases where parent and child have different
Thu, 5 Mar 2009 17:30:29 +0000 (17:30 +0000)
Thu, 5 Mar 2009 17:30:29 +0000 (17:30 +0000)
attribute numbering. Also, a parent whole-row reference should not require
select privilege on child columns that aren't inherited from the parent.
Problem diagnosed by KaiGai Kohei, though this isn't exactly his patch.


diff --git a/src/backend/optimizer/prep/prepunion.c b/src/backend/optimizer/prep/prepunion.c
index 13d08eef3eec666f984f6bc310d49bb24bcfb59e..43aa515ae5efa404d133c1c41fb6df69587ca7ba 100644 (file)
--- a/src/backend/optimizer/prep/prepunion.c
+++ b/src/backend/optimizer/prep/prepunion.c
@@ -22,7 +22,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/prep/prepunion.c,v 1.166 2009年02月25日 03:30:37 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/prep/prepunion.c,v 1.167 2009年03月05日 17:30:29 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -30,6 +30,7 @@
#include "access/heapam.h"
+#include "access/sysattr.h"
#include "catalog/namespace.h"
#include "catalog/pg_type.h"
#include "miscadmin.h"
@@ -95,6 +96,8 @@ static void make_inh_translation_list(Relation oldrelation,
Relation newrelation,
Index newvarno,
List **translated_vars);
+static Bitmapset *translate_col_privs(const Bitmapset *parent_privs,
+ List *translated_vars);
static Node *adjust_appendrel_attrs_mutator(Node *node,
AppendRelInfo *context);
static Relids adjust_relid_set(Relids relids, Index oldrelid, Index newrelid);
@@ -1295,6 +1298,19 @@ expand_inherited_rtentry(PlannerInfo *root, RangeTblEntry *rte, Index rti)
appinfo->parent_reloid = parentOID;
appinfos = lappend(appinfos, appinfo);
+ /*
+ * Translate the column permissions bitmaps to the child's attnums
+ * (we have to build the translated_vars list before we can do this).
+ * But if this is the parent table, leave copyObject's result alone.
+ */
+ if (childOID != parentOID)
+ {
+ childrte->selectedCols = translate_col_privs(rte->selectedCols,
+ appinfo->translated_vars);
+ childrte->modifiedCols = translate_col_privs(rte->modifiedCols,
+ appinfo->translated_vars);
+ }
+
/*
* Build a RowMarkClause if parent is marked FOR UPDATE/SHARE.
*/
@@ -1437,6 +1453,59 @@ make_inh_translation_list(Relation oldrelation, Relation newrelation,
*translated_vars = vars;
}
+/*
+ * translate_col_privs
+ * Translate a bitmapset representing per-column privileges from the
+ * parent rel's attribute numbering to the child's.
+ *
+ * The only surprise here is that we don't translate a parent whole-row
+ * reference into a child whole-row reference. That would mean requiring
+ * permissions on all child columns, which is overly strict, since the
+ * query is really only going to reference the inherited columns. Instead
+ * we set the per-column bits for all inherited columns.
+ */
+static Bitmapset *
+translate_col_privs(const Bitmapset *parent_privs,
+ List *translated_vars)
+{
+ Bitmapset *child_privs = NULL;
+ bool whole_row;
+ int attno;
+ ListCell *lc;
+
+ /* System attributes have the same numbers in all tables */
+ for (attno = FirstLowInvalidHeapAttributeNumber+1; attno < 0; attno++)
+ {
+ if (bms_is_member(attno - FirstLowInvalidHeapAttributeNumber,
+ parent_privs))
+ child_privs = bms_add_member(child_privs,
+ attno - FirstLowInvalidHeapAttributeNumber);
+ }
+
+ /* Check if parent has whole-row reference */
+ whole_row = bms_is_member(InvalidAttrNumber - FirstLowInvalidHeapAttributeNumber,
+ parent_privs);
+
+ /* And now translate the regular user attributes, using the vars list */
+ attno = InvalidAttrNumber;
+ foreach(lc, translated_vars)
+ {
+ Var *var = (Var *) lfirst(lc);
+
+ attno++;
+ if (var == NULL) /* ignore dropped columns */
+ continue;
+ Assert(IsA(var, Var));
+ if (whole_row ||
+ bms_is_member(attno - FirstLowInvalidHeapAttributeNumber,
+ parent_privs))
+ child_privs = bms_add_member(child_privs,
+ var->varattno - FirstLowInvalidHeapAttributeNumber);
+ }
+
+ return child_privs;
+}
+
/*
* adjust_appendrel_attrs
* Copy the specified query or expression and translate Vars referring
diff --git a/src/test/regress/expected/privileges.out b/src/test/regress/expected/privileges.out
index 8129f5b915b0e3d8c8a6bbd91f5d72516ae98f11..a17ff59d0c81182b11f094c21ec7c1ef00cc55e0 100644 (file)
--- a/src/test/regress/expected/privileges.out
+++ b/src/test/regress/expected/privileges.out
@@ -393,6 +393,48 @@ SET SESSION AUTHORIZATION regressuser3;
DELETE FROM atest5 WHERE one = 1; -- fail
ERROR: permission denied for relation atest5
DELETE FROM atest5 WHERE two = 2; -- ok
+-- check inheritance cases
+SET SESSION AUTHORIZATION regressuser1;
+CREATE TABLE atestp1 (f1 int, f2 int) WITH OIDS;
+CREATE TABLE atestp2 (fx int, fy int) WITH OIDS;
+CREATE TABLE atestc (fz int) INHERITS (atestp1, atestp2);
+GRANT SELECT(fx,fy,oid) ON atestp2 TO regressuser2;
+GRANT SELECT(fx) ON atestc TO regressuser2;
+SET SESSION AUTHORIZATION regressuser2;
+SELECT fx FROM atestp2; -- ok
+ fx
+----
+(0 rows)
+
+SELECT fy FROM atestp2; -- fail, no privilege on atestc.fy
+ERROR: permission denied for relation atestc
+SELECT atestp2 FROM atestp2; -- fail, no privilege on atestc.fy
+ERROR: permission denied for relation atestc
+SELECT oid FROM atestp2; -- fail, no privilege on atestc.oid
+ERROR: permission denied for relation atestc
+SET SESSION AUTHORIZATION regressuser1;
+GRANT SELECT(fy,oid) ON atestc TO regressuser2;
+SET SESSION AUTHORIZATION regressuser2;
+SELECT fx FROM atestp2; -- still ok
+ fx
+----
+(0 rows)
+
+SELECT fy FROM atestp2; -- ok
+ fy
+----
+(0 rows)
+
+SELECT atestp2 FROM atestp2; -- ok
+ atestp2
+---------
+(0 rows)
+
+SELECT oid FROM atestp2; -- ok
+ oid
+-----
+(0 rows)
+
-- privileges on functions, languages
-- switch to superuser
\c -
@@ -791,6 +833,9 @@ DROP TABLE atest3;
DROP TABLE atest4;
DROP TABLE atest5;
DROP TABLE atest6;
+DROP TABLE atestc;
+DROP TABLE atestp1;
+DROP TABLE atestp2;
DROP GROUP regressgroup1;
DROP GROUP regressgroup2;
REVOKE USAGE ON LANGUAGE sql FROM regressuser1;
diff --git a/src/test/regress/sql/privileges.sql b/src/test/regress/sql/privileges.sql
index 2316d1161628fe11d920ed47fe8d3986d28eda70..5aa1012f3f619de7befd2d2222874d6a6c938a7e 100644 (file)
--- a/src/test/regress/sql/privileges.sql
+++ b/src/test/regress/sql/privileges.sql
@@ -267,6 +267,29 @@ SET SESSION AUTHORIZATION regressuser3;
DELETE FROM atest5 WHERE one = 1; -- fail
DELETE FROM atest5 WHERE two = 2; -- ok
+-- check inheritance cases
+SET SESSION AUTHORIZATION regressuser1;
+CREATE TABLE atestp1 (f1 int, f2 int) WITH OIDS;
+CREATE TABLE atestp2 (fx int, fy int) WITH OIDS;
+CREATE TABLE atestc (fz int) INHERITS (atestp1, atestp2);
+GRANT SELECT(fx,fy,oid) ON atestp2 TO regressuser2;
+GRANT SELECT(fx) ON atestc TO regressuser2;
+
+SET SESSION AUTHORIZATION regressuser2;
+SELECT fx FROM atestp2; -- ok
+SELECT fy FROM atestp2; -- fail, no privilege on atestc.fy
+SELECT atestp2 FROM atestp2; -- fail, no privilege on atestc.fy
+SELECT oid FROM atestp2; -- fail, no privilege on atestc.oid
+
+SET SESSION AUTHORIZATION regressuser1;
+GRANT SELECT(fy,oid) ON atestc TO regressuser2;
+
+SET SESSION AUTHORIZATION regressuser2;
+SELECT fx FROM atestp2; -- still ok
+SELECT fy FROM atestp2; -- ok
+SELECT atestp2 FROM atestp2; -- ok
+SELECT oid FROM atestp2; -- ok
+
-- privileges on functions, languages
-- switch to superuser
@@ -466,6 +489,9 @@ DROP TABLE atest3;
DROP TABLE atest4;
DROP TABLE atest5;
DROP TABLE atest6;
+DROP TABLE atestc;
+DROP TABLE atestp1;
+DROP TABLE atestp2;
DROP GROUP regressgroup1;
DROP GROUP regressgroup2;
This is the main PostgreSQL git repository.
RSS Atom

AltStyle によって変換されたページ (->オリジナル) /