Change the aclchk.c routines to uniformly use OIDs to identify the
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 21 Mar 2002 23:27:25 +0000 (23:27 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 21 Mar 2002 23:27:25 +0000 (23:27 +0000)
objects to be privilege-checked.  Some change in their APIs would be
necessary no matter what in the schema environment, and simply getting
rid of the name-based interface entirely seems like the best way.

22 files changed:
src/backend/catalog/aclchk.c
src/backend/commands/analyze.c
src/backend/commands/command.c
src/backend/commands/comment.c
src/backend/commands/copy.c
src/backend/commands/creatinh.c
src/backend/commands/remove.c
src/backend/commands/rename.c
src/backend/commands/sequence.c
src/backend/commands/trigger.c
src/backend/commands/vacuum.c
src/backend/executor/execMain.c
src/backend/rewrite/rewriteDefine.c
src/backend/rewrite/rewriteRemove.c
src/backend/tcop/utility.c
src/backend/utils/adt/acl.c
src/backend/utils/cache/syscache.c
src/include/rewrite/rewriteRemove.h
src/include/utils/acl.h
src/include/utils/syscache.h
src/test/regress/expected/errors.out
src/test/regress/expected/privileges.out

index 2244827f7c4ec39f0e0ddeac0b944c00dfd89436..2225dc3a14ef6465dfa7e36e5087d21132092cb1 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.57 2002/03/21 16:00:29 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.58 2002/03/21 23:27:19 tgl Exp $
  *
  * NOTES
  *       See acl.h.
@@ -50,8 +50,8 @@ static const char *privilege_token_string(int token);
 static int32 aclcheck(Acl *acl, AclId id, AclIdType idtype, AclMode mode);
 
 /* warning messages, now more explicit. */
-/* MUST correspond to the order of the ACLCHK_* result codes in acl.h. */
-char      *aclcheck_error_strings[] = {
+/* MUST correspond to the order of the ACLCHECK_* result codes in acl.h. */
+const char * const aclcheck_error_strings[] = {
        "No error.",
        "Permission denied.",
        "Table does not exist.",
@@ -66,11 +66,11 @@ dumpacl(Acl *acl)
        int                     i;
        AclItem    *aip;
 
-       elog(LOG, "acl size = %d, # acls = %d",
+       elog(DEBUG1, "acl size = %d, # acls = %d",
                 ACL_SIZE(acl), ACL_NUM(acl));
        aip = ACL_DAT(acl);
        for (i = 0; i < ACL_NUM(acl); ++i)
-               elog(LOG, "     acl[%d]: %s", i,
+               elog(DEBUG1, "  acl[%d]: %s", i,
                         DatumGetCString(DirectFunctionCall1(aclitemout,
                                                                                         PointerGetDatum(aip + i))));
 }
@@ -214,23 +214,20 @@ ExecuteGrantStmt_Table(GrantStmt *stmt)
                char            nulls[Natts_pg_class];
                char            replaces[Natts_pg_class];
 
-
-               if (!pg_ownercheck(GetUserId(), relname, RELNAME))
-                       elog(ERROR, "permission denied");
-
                /* open pg_class */
                relation = heap_openr(RelationRelationName, RowExclusiveLock);
                tuple = SearchSysCache(RELNAME,
                                                           PointerGetDatum(relname),
                                                           0, 0, 0);
                if (!HeapTupleIsValid(tuple))
-               {
-                       heap_close(relation, RowExclusiveLock);
                        elog(ERROR, "relation \"%s\" not found",
                                 relname);
-               }
                pg_class_tuple = (Form_pg_class) GETSTRUCT(tuple);
 
+               if (!pg_class_ownercheck(tuple->t_data->t_oid, GetUserId()))
+                       elog(ERROR, "%s: permission denied",
+                                relname);
+
                if (pg_class_tuple->relkind == RELKIND_INDEX)
                        elog(ERROR, "\"%s\" is an index",
                                 relname);
@@ -658,7 +655,7 @@ aclcheck(Acl *acl, AclId id, AclIdType idtype, AclMode mode)
         */
        if (!acl)
        {
-               elog(LOG, "aclcheck: null ACL, returning OK");
+               elog(DEBUG1, "aclcheck: null ACL, returning OK");
                return ACLCHECK_OK;
        }
 
@@ -673,7 +670,7 @@ aclcheck(Acl *acl, AclId id, AclIdType idtype, AclMode mode)
         */
        if (num < 1)
        {
-               elog(LOG, "aclcheck: zero-length ACL, returning OK");
+               elog(DEBUG1, "aclcheck: zero-length ACL, returning OK");
                return ACLCHECK_OK;
        }
 
@@ -686,7 +683,7 @@ aclcheck(Acl *acl, AclId id, AclIdType idtype, AclMode mode)
        if (aidat->ai_mode & mode)
        {
 #ifdef ACLDEBUG
-               elog(LOG, "aclcheck: using world=%d", aidat->ai_mode);
+               elog(DEBUG1, "aclcheck: using world=%d", aidat->ai_mode);
 #endif
                return ACLCHECK_OK;
        }
@@ -702,7 +699,7 @@ aclcheck(Acl *acl, AclId id, AclIdType idtype, AclMode mode)
                                if (aip->ai_id == id)
                                {
 #ifdef ACLDEBUG
-                                       elog(LOG, "aclcheck: found user %u/%d",
+                                       elog(DEBUG1, "aclcheck: found user %u/%d",
                                                 aip->ai_id, aip->ai_mode);
 #endif
                                        if (aip->ai_mode & mode)
@@ -719,7 +716,7 @@ aclcheck(Acl *acl, AclId id, AclIdType idtype, AclMode mode)
                                        if (in_group(id, aip->ai_id))
                                        {
 #ifdef ACLDEBUG
-                                               elog(LOG, "aclcheck: found group %u/%d",
+                                               elog(DEBUG1, "aclcheck: found group %u/%d",
                                                         aip->ai_id, aip->ai_mode);
 #endif
                                                return ACLCHECK_OK;
@@ -740,7 +737,7 @@ aclcheck(Acl *acl, AclId id, AclIdType idtype, AclMode mode)
                                if (aip->ai_id == id)
                                {
 #ifdef ACLDEBUG
-                                       elog(LOG, "aclcheck: found group %u/%d",
+                                       elog(DEBUG1, "aclcheck: found group %u/%d",
                                                 aip->ai_id, aip->ai_mode);
 #endif
                                        if (aip->ai_mode & mode)
@@ -760,46 +757,63 @@ aclcheck(Acl *acl, AclId id, AclIdType idtype, AclMode mode)
        return ACLCHECK_NO_PRIV;
 }
 
+
 /*
  * Exported routine for checking a user's access privileges to a table
  *
  * Returns an ACLCHECK_* result code.
  */
 int32
-pg_aclcheck(char *relname, Oid userid, AclMode mode)
+pg_class_aclcheck(Oid table_oid, Oid userid, AclMode mode)
 {
        int32           result;
+       bool            usesuper,
+                               usecatupd;
+       char       *relname;
        HeapTuple       tuple;
-       char       *usename;
        Datum           aclDatum;
        bool            isNull;
        Acl                *acl;
 
        /*
         * Validate userid, find out if he is superuser
+        *
+        * We do not use superuser_arg() here because we also need to check
+        * usecatupd.
         */
        tuple = SearchSysCache(SHADOWSYSID,
                                                   ObjectIdGetDatum(userid),
                                                   0, 0, 0);
        if (!HeapTupleIsValid(tuple))
-               elog(ERROR, "pg_aclcheck: invalid user id %u",
-                        (unsigned) userid);
+               elog(ERROR, "pg_class_aclcheck: invalid user id %u", userid);
 
-       usename = NameStr(((Form_pg_shadow) GETSTRUCT(tuple))->usename);
+       usesuper = ((Form_pg_shadow) GETSTRUCT(tuple))->usesuper;
+       usecatupd = ((Form_pg_shadow) GETSTRUCT(tuple))->usecatupd;
+
+       ReleaseSysCache(tuple);
+
+       /*
+        * Now get the relation's tuple from pg_class
+        */
+       tuple = SearchSysCache(RELOID,
+                                                  ObjectIdGetDatum(table_oid),
+                                                  0, 0, 0);
+       if (!HeapTupleIsValid(tuple))
+               elog(ERROR, "pg_class_aclcheck: relation %u not found", table_oid);
 
        /*
         * Deny anyone permission to update a system catalog unless
         * pg_shadow.usecatupd is set.  (This is to let superusers protect
         * themselves from themselves.)
         */
+       relname = NameStr(((Form_pg_class) GETSTRUCT(tuple))->relname);
        if ((mode & (ACL_INSERT | ACL_UPDATE | ACL_DELETE)) &&
                !allowSystemTableMods && IsSystemRelationName(relname) &&
                !is_temp_relname(relname) &&
-               !((Form_pg_shadow) GETSTRUCT(tuple))->usecatupd)
+               !usecatupd)
        {
 #ifdef ACLDEBUG
-               elog(LOG, "pg_aclcheck: catalog update to \"%s\": permission denied",
-                        relname);
+               elog(DEBUG1, "pg_class_aclcheck: catalog update: permission denied");
 #endif
                ReleaseSysCache(tuple);
                return ACLCHECK_NO_PRIV;
@@ -808,29 +822,19 @@ pg_aclcheck(char *relname, Oid userid, AclMode mode)
        /*
         * Otherwise, superusers bypass all permission-checking.
         */
-       if (((Form_pg_shadow) GETSTRUCT(tuple))->usesuper)
+       if (usesuper)
        {
 #ifdef ACLDEBUG
-               elog(LOG, "pg_aclcheck: \"%s\" is superuser",
-                        usename);
+               elog(DEBUG1, "pg_class_aclcheck: %u is superuser", userid);
 #endif
                ReleaseSysCache(tuple);
                return ACLCHECK_OK;
        }
 
-       ReleaseSysCache(tuple);
-       /* caution: usename is inaccessible beyond this point... */
-
        /*
         * Normal case: get the relation's ACL from pg_class
         */
-       tuple = SearchSysCache(RELNAME,
-                                                  PointerGetDatum(relname),
-                                                  0, 0, 0);
-       if (!HeapTupleIsValid(tuple))
-               elog(ERROR, "pg_aclcheck: class \"%s\" not found", relname);
-
-       aclDatum = SysCacheGetAttr(RELNAME, tuple, Anum_pg_class_relacl,
+       aclDatum = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_relacl,
                                                           &isNull);
        if (isNull)
        {
@@ -858,227 +862,6 @@ pg_aclcheck(char *relname, Oid userid, AclMode mode)
        return result;
 }
 
-/*
- * Check ownership of an object identified by name (which will be looked
- * up in the system cache identified by cacheid).
- *
- * Returns true if userid owns the item, or should be allowed to modify
- * the item as if he owned it.
- */
-bool
-pg_ownercheck(Oid userid,
-                         const char *name,
-                         int cacheid)
-{
-       HeapTuple       tuple;
-       AclId           owner_id;
-       char       *usename;
-
-       tuple = SearchSysCache(SHADOWSYSID,
-                                                  ObjectIdGetDatum(userid),
-                                                  0, 0, 0);
-       if (!HeapTupleIsValid(tuple))
-               elog(ERROR, "pg_ownercheck: invalid user id %u",
-                        (unsigned) userid);
-       usename = NameStr(((Form_pg_shadow) GETSTRUCT(tuple))->usename);
-
-       /*
-        * Superusers bypass all permission-checking.
-        */
-       if (((Form_pg_shadow) GETSTRUCT(tuple))->usesuper)
-       {
-#ifdef ACLDEBUG
-               elog(LOG, "pg_ownercheck: user \"%s\" is superuser",
-                        usename);
-#endif
-               ReleaseSysCache(tuple);
-               return true;
-       }
-
-       ReleaseSysCache(tuple);
-       /* caution: usename is inaccessible beyond this point... */
-
-       tuple = SearchSysCache(cacheid,
-                                                  PointerGetDatum(name),
-                                                  0, 0, 0);
-       switch (cacheid)
-       {
-               case RELNAME:
-                       if (!HeapTupleIsValid(tuple))
-                               elog(ERROR, "pg_ownercheck: class \"%s\" not found",
-                                        name);
-                       owner_id = ((Form_pg_class) GETSTRUCT(tuple))->relowner;
-                       break;
-               case TYPENAME:
-                       if (!HeapTupleIsValid(tuple))
-                               elog(ERROR, "pg_ownercheck: type \"%s\" not found",
-                                        name);
-                       owner_id = ((Form_pg_type) GETSTRUCT(tuple))->typowner;
-                       break;
-               default:
-                       elog(ERROR, "pg_ownercheck: invalid cache id: %d", cacheid);
-                       owner_id = 0;           /* keep compiler quiet */
-                       break;
-       }
-
-       ReleaseSysCache(tuple);
-
-       return userid == owner_id;
-}
-
-/*
- * Ownership check for an operator (specified by OID).
- */
-bool
-pg_oper_ownercheck(Oid userid, Oid oprid)
-{
-       HeapTuple       tuple;
-       AclId           owner_id;
-       char       *usename;
-
-       tuple = SearchSysCache(SHADOWSYSID,
-                                                  ObjectIdGetDatum(userid),
-                                                  0, 0, 0);
-       if (!HeapTupleIsValid(tuple))
-               elog(ERROR, "pg_oper_ownercheck: invalid user id %u",
-                        (unsigned) userid);
-       usename = NameStr(((Form_pg_shadow) GETSTRUCT(tuple))->usename);
-
-       /*
-        * Superusers bypass all permission-checking.
-        */
-       if (((Form_pg_shadow) GETSTRUCT(tuple))->usesuper)
-       {
-#ifdef ACLDEBUG
-               elog(LOG, "pg_ownercheck: user \"%s\" is superuser",
-                        usename);
-#endif
-               ReleaseSysCache(tuple);
-               return true;
-       }
-
-       ReleaseSysCache(tuple);
-       /* caution: usename is inaccessible beyond this point... */
-
-       tuple = SearchSysCache(OPEROID,
-                                                  ObjectIdGetDatum(oprid),
-                                                  0, 0, 0);
-       if (!HeapTupleIsValid(tuple))
-               elog(ERROR, "pg_ownercheck: operator %u not found",
-                        oprid);
-
-       owner_id = ((Form_pg_operator) GETSTRUCT(tuple))->oprowner;
-
-       ReleaseSysCache(tuple);
-
-       return userid == owner_id;
-}
-
-/*
- * Ownership check for a function (specified by name and argument types).
- */
-bool
-pg_func_ownercheck(Oid userid,
-                                  char *funcname,
-                                  int nargs,
-                                  Oid *arglist)
-{
-       HeapTuple       tuple;
-       AclId           owner_id;
-       char       *usename;
-
-       tuple = SearchSysCache(SHADOWSYSID,
-                                                  ObjectIdGetDatum(userid),
-                                                  0, 0, 0);
-       if (!HeapTupleIsValid(tuple))
-               elog(ERROR, "pg_func_ownercheck: invalid user id %u",
-                        (unsigned) userid);
-       usename = NameStr(((Form_pg_shadow) GETSTRUCT(tuple))->usename);
-
-       /*
-        * Superusers bypass all permission-checking.
-        */
-       if (((Form_pg_shadow) GETSTRUCT(tuple))->usesuper)
-       {
-#ifdef ACLDEBUG
-               elog(LOG, "pg_ownercheck: user \"%s\" is superuser",
-                        usename);
-#endif
-               ReleaseSysCache(tuple);
-               return true;
-       }
-
-       ReleaseSysCache(tuple);
-       /* caution: usename is inaccessible beyond this point... */
-
-       tuple = SearchSysCache(PROCNAME,
-                                                  PointerGetDatum(funcname),
-                                                  Int32GetDatum(nargs),
-                                                  PointerGetDatum(arglist),
-                                                  0);
-       if (!HeapTupleIsValid(tuple))
-               func_error("pg_func_ownercheck", funcname, nargs, arglist, NULL);
-
-       owner_id = ((Form_pg_proc) GETSTRUCT(tuple))->proowner;
-
-       ReleaseSysCache(tuple);
-
-       return userid == owner_id;
-}
-
-/*
- * Ownership check for an aggregate function (specified by name and
- * argument type).
- */
-bool
-pg_aggr_ownercheck(Oid userid,
-                                  char *aggname,
-                                  Oid basetypeID)
-{
-       HeapTuple       tuple;
-       AclId           owner_id;
-       char       *usename;
-
-       tuple = SearchSysCache(SHADOWSYSID,
-                                                  PointerGetDatum(userid),
-                                                  0, 0, 0);
-       if (!HeapTupleIsValid(tuple))
-               elog(ERROR, "pg_aggr_ownercheck: invalid user id %u",
-                        (unsigned) userid);
-       usename = NameStr(((Form_pg_shadow) GETSTRUCT(tuple))->usename);
-
-       /*
-        * Superusers bypass all permission-checking.
-        */
-       if (((Form_pg_shadow) GETSTRUCT(tuple))->usesuper)
-       {
-#ifdef ACLDEBUG
-               elog(LOG, "pg_aggr_ownercheck: user \"%s\" is superuser",
-                        usename);
-#endif
-               ReleaseSysCache(tuple);
-               return true;
-       }
-
-       ReleaseSysCache(tuple);
-       /* caution: usename is inaccessible beyond this point... */
-
-       tuple = SearchSysCache(AGGNAME,
-                                                  PointerGetDatum(aggname),
-                                                  ObjectIdGetDatum(basetypeID),
-                                                  0, 0);
-       if (!HeapTupleIsValid(tuple))
-               agg_error("pg_aggr_ownercheck", aggname, basetypeID);
-
-       owner_id = ((Form_pg_aggregate) GETSTRUCT(tuple))->aggowner;
-
-       ReleaseSysCache(tuple);
-
-       return userid == owner_id;
-}
-
-
-
 /*
  * Exported routine for checking a user's access privileges to a function
  *
@@ -1093,22 +876,12 @@ pg_proc_aclcheck(Oid proc_oid, Oid userid)
        bool            isNull;
        Acl                *acl;
 
+       /* Superusers bypass all permission checking. */
        if (superuser_arg(userid))
                return ACLCHECK_OK;
 
        /*
-        * Validate userid
-        */
-       tuple = SearchSysCache(SHADOWSYSID,
-                                                  ObjectIdGetDatum(userid),
-                                                  0, 0, 0);
-       if (!HeapTupleIsValid(tuple))
-               elog(ERROR, "pg_proc_aclcheck: invalid user id %u",
-                        (unsigned) userid);
-       ReleaseSysCache(tuple);
-
-       /*
-        * Normal case: get the function's ACL from pg_proc
+        * Get the function's ACL from pg_proc
         */
        tuple = SearchSysCache(PROCOID,
                                                   ObjectIdGetDatum(proc_oid),
@@ -1148,8 +921,6 @@ pg_proc_aclcheck(Oid proc_oid, Oid userid)
        return result;
 }
 
-
-
 /*
  * Exported routine for checking a user's access privileges to a language
  *
@@ -1164,22 +935,12 @@ pg_language_aclcheck(Oid lang_oid, Oid userid)
        bool            isNull;
        Acl                *acl;
 
+       /* Superusers bypass all permission checking. */
        if (superuser_arg(userid))
                return ACLCHECK_OK;
 
        /*
-        * Validate userid
-        */
-       tuple = SearchSysCache(SHADOWSYSID,
-                                                  ObjectIdGetDatum(userid),
-                                                  0, 0, 0);
-       if (!HeapTupleIsValid(tuple))
-               elog(ERROR, "pg_language_aclcheck: invalid user id %u",
-                        (unsigned) userid);
-       ReleaseSysCache(tuple);
-
-       /*
-        * Normal case: get the function's ACL from pg_language
+        * Get the function's ACL from pg_language
         */
        tuple = SearchSysCache(LANGOID,
                                                   ObjectIdGetDatum(lang_oid),
@@ -1215,3 +976,134 @@ pg_language_aclcheck(Oid lang_oid, Oid userid)
 
        return result;
 }
+
+
+/*
+ * Ownership check for a relation (specified by OID).
+ */
+bool
+pg_class_ownercheck(Oid class_oid, Oid userid)
+{
+       HeapTuple       tuple;
+       AclId           owner_id;
+
+       /* Superusers bypass all permission checking. */
+       if (superuser_arg(userid))
+               return true;
+
+       tuple = SearchSysCache(RELOID,
+                                                  ObjectIdGetDatum(class_oid),
+                                                  0, 0, 0);
+       if (!HeapTupleIsValid(tuple))
+               elog(ERROR, "pg_class_ownercheck: relation %u not found", class_oid);
+
+       owner_id = ((Form_pg_class) GETSTRUCT(tuple))->relowner;
+
+       ReleaseSysCache(tuple);
+
+       return userid == owner_id;
+}
+
+/*
+ * Ownership check for a type (specified by OID).
+ */
+bool
+pg_type_ownercheck(Oid type_oid, Oid userid)
+{
+       HeapTuple       tuple;
+       AclId           owner_id;
+
+       /* Superusers bypass all permission checking. */
+       if (superuser_arg(userid))
+               return true;
+
+       tuple = SearchSysCache(TYPEOID,
+                                                  ObjectIdGetDatum(type_oid),
+                                                  0, 0, 0);
+       if (!HeapTupleIsValid(tuple))
+               elog(ERROR, "pg_type_ownercheck: type %u not found", type_oid);
+
+       owner_id = ((Form_pg_type) GETSTRUCT(tuple))->typowner;
+
+       ReleaseSysCache(tuple);
+
+       return userid == owner_id;
+}
+
+/*
+ * Ownership check for an operator (specified by OID).
+ */
+bool
+pg_oper_ownercheck(Oid oper_oid, Oid userid)
+{
+       HeapTuple       tuple;
+       AclId           owner_id;
+
+       /* Superusers bypass all permission checking. */
+       if (superuser_arg(userid))
+               return true;
+
+       tuple = SearchSysCache(OPEROID,
+                                                  ObjectIdGetDatum(oper_oid),
+                                                  0, 0, 0);
+       if (!HeapTupleIsValid(tuple))
+               elog(ERROR, "pg_oper_ownercheck: operator %u not found", oper_oid);
+
+       owner_id = ((Form_pg_operator) GETSTRUCT(tuple))->oprowner;
+
+       ReleaseSysCache(tuple);
+
+       return userid == owner_id;
+}
+
+/*
+ * Ownership check for a function (specified by OID).
+ */
+bool
+pg_proc_ownercheck(Oid proc_oid, Oid userid)
+{
+       HeapTuple       tuple;
+       AclId           owner_id;
+
+       /* Superusers bypass all permission checking. */
+       if (superuser_arg(userid))
+               return true;
+
+       tuple = SearchSysCache(PROCOID,
+                                                  ObjectIdGetDatum(proc_oid),
+                                                  0, 0, 0);
+       if (!HeapTupleIsValid(tuple))
+               elog(ERROR, "pg_proc_ownercheck: function %u not found", proc_oid);
+
+       owner_id = ((Form_pg_proc) GETSTRUCT(tuple))->proowner;
+
+       ReleaseSysCache(tuple);
+
+       return userid == owner_id;
+}
+
+/*
+ * Ownership check for an aggregate function (specified by OID).
+ */
+bool
+pg_aggr_ownercheck(Oid aggr_oid, Oid userid)
+{
+       HeapTuple       tuple;
+       AclId           owner_id;
+
+       /* Superusers bypass all permission checking. */
+       if (superuser_arg(userid))
+               return true;
+
+       tuple = SearchSysCache(AGGOID,
+                                                  ObjectIdGetDatum(aggr_oid),
+                                                  0, 0, 0);
+       if (!HeapTupleIsValid(tuple))
+               elog(ERROR, "pg_aggr_ownercheck: aggregate %u not found", aggr_oid);
+
+       owner_id = ((Form_pg_aggregate) GETSTRUCT(tuple))->aggowner;
+
+       ReleaseSysCache(tuple);
+
+       return userid == owner_id;
+}
index d033fa950542c2f7959a7504a1e42246f58a36d3..df9735089aab470a10a334753db3e7d12649c586 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/commands/analyze.c,v 1.28 2002/03/06 06:09:28 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/commands/analyze.c,v 1.29 2002/03/21 23:27:20 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -200,8 +200,7 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt)
         */
        onerel = heap_open(relid, AccessShareLock);
 
-       if (!(pg_ownercheck(GetUserId(), RelationGetRelationName(onerel),
-                                               RELNAME) ||
+       if (!(pg_class_ownercheck(RelationGetRelid(onerel), GetUserId()) ||
                  (is_dbadmin(MyDatabaseId) && !onerel->rd_rel->relisshared)))
        {
                /* No need for a WARNING if we already complained during VACUUM */
index 5821e1d10366acc1ca49b77e12ea0abe1dc1ed5f..31df6cabd77ccbedabe39c3665cd0a11d3ccd3b3 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.162 2002/03/21 16:00:31 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.163 2002/03/21 23:27:20 tgl Exp $
  *
  * NOTES
  *       The PerformAddAttribute() code, like most of the relation
@@ -327,6 +327,17 @@ AlterTableAddColumn(const char *relationName,
        char       *typename;
        int                     attndims;
 
+       /*
+        * Grab an exclusive lock on the target table, which we will NOT
+        * release until end of transaction.
+        */
+       rel = heap_openr(relationName, AccessExclusiveLock);
+       myrelid = RelationGetRelid(rel);
+
+       if (rel->rd_rel->relkind != RELKIND_RELATION)
+               elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table",
+                        relationName);
+
        /*
         * permissions checking.  this would normally be done in utility.c,
         * but this particular routine is recursive.
@@ -336,20 +347,9 @@ AlterTableAddColumn(const char *relationName,
        if (!allowSystemTableMods && IsSystemRelationName(relationName))
                elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog",
                         relationName);
-       if (!pg_ownercheck(GetUserId(), relationName, RELNAME))
+       if (!pg_class_ownercheck(myrelid, GetUserId()))
                elog(ERROR, "ALTER TABLE: permission denied");
 
-       /*
-        * Grab an exclusive lock on the target table, which we will NOT
-        * release until end of transaction.
-        */
-       rel = heap_openr(relationName, AccessExclusiveLock);
-
-       if (rel->rd_rel->relkind != RELKIND_RELATION)
-               elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table",
-                        relationName);
-
-       myrelid = RelationGetRelid(rel);
        heap_close(rel, NoLock);        /* close rel but keep lock! */
 
        /*
@@ -556,21 +556,19 @@ AlterTableAlterColumnDefault(const char *relationName,
        int16           attnum;
        Oid                     myrelid;
 
-       if (!allowSystemTableMods && IsSystemRelationName(relationName))
-               elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog",
-                        relationName);
-#ifndef NO_SECURITY
-       if (!pg_ownercheck(GetUserId(), relationName, RELNAME))
-               elog(ERROR, "ALTER TABLE: permission denied");
-#endif
-
        rel = heap_openr(relationName, AccessExclusiveLock);
+       myrelid = RelationGetRelid(rel);
 
        if (rel->rd_rel->relkind != RELKIND_RELATION)
                elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table",
                         relationName);
 
-       myrelid = RelationGetRelid(rel);
+       if (!allowSystemTableMods && IsSystemRelationName(relationName))
+               elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog",
+                        relationName);
+       if (!pg_class_ownercheck(myrelid, GetUserId()))
+               elog(ERROR, "ALTER TABLE: permission denied");
+
        heap_close(rel, NoLock);
 
        /*
@@ -730,24 +728,21 @@ AlterTableAlterColumnFlags(const char *relationName,
        Relation        attrelation;
        HeapTuple       tuple;
 
-       /* we allow statistics case for system tables */
-
-       if (*flagType =='M' && !allowSystemTableMods && IsSystemRelationName(relationName))
-               elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog",
-                        relationName);
-
-#ifndef NO_SECURITY
-       if (!pg_ownercheck(GetUserId(), relationName, RELNAME))
-               elog(ERROR, "ALTER TABLE: permission denied");
-#endif
-
        rel = heap_openr(relationName, AccessExclusiveLock);
+       myrelid = RelationGetRelid(rel);
 
        if (rel->rd_rel->relkind != RELKIND_RELATION)
                elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table",
                         relationName);
 
-       myrelid = RelationGetRelid(rel);
+       /* we allow statistics case for system tables */
+       if (*flagType == 'M' &&
+               !allowSystemTableMods && IsSystemRelationName(relationName))
+               elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog",
+                        relationName);
+       if (!pg_class_ownercheck(myrelid, GetUserId()))
+               elog(ERROR, "ALTER TABLE: permission denied");
+
        heap_close(rel, NoLock);        /* close rel, but keep lock! */
 
 
@@ -1034,6 +1029,17 @@ AlterTableDropColumn(const char *relationName,
        if (inh)
                elog(ERROR, "ALTER TABLE / DROP COLUMN with inherit option is not supported yet");
 
+       /*
+        * Grab an exclusive lock on the target table, which we will NOT
+        * release until end of transaction.
+        */
+       rel = heap_openr(relationName, AccessExclusiveLock);
+       myrelid = RelationGetRelid(rel);
+
+       if (rel->rd_rel->relkind != RELKIND_RELATION)
+               elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table",
+                        relationName);
+
        /*
         * permissions checking.  this would normally be done in utility.c,
         * but this particular routine is recursive.
@@ -1043,22 +1049,9 @@ AlterTableDropColumn(const char *relationName,
        if (!allowSystemTableMods && IsSystemRelationName(relationName))
                elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog",
                         relationName);
-#ifndef NO_SECURITY
-       if (!pg_ownercheck(GetUserId(), relationName, RELNAME))
+       if (!pg_class_ownercheck(myrelid, GetUserId()))
                elog(ERROR, "ALTER TABLE: permission denied");
-#endif
-
-       /*
-        * Grab an exclusive lock on the target table, which we will NOT
-        * release until end of transaction.
-        */
-       rel = heap_openr(relationName, AccessExclusiveLock);
-
-       if (rel->rd_rel->relkind != RELKIND_RELATION)
-               elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table",
-                        relationName);
 
-       myrelid = RelationGetRelid(rel);
        heap_close(rel, NoLock);        /* close rel but keep lock! */
 
        /*
@@ -1180,25 +1173,22 @@ AlterTableAddConstraint(char *relationName,
        Oid                     myrelid;
        List       *listptr;
 
-       if (!allowSystemTableMods && IsSystemRelationName(relationName))
-               elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog",
-                        relationName);
-#ifndef NO_SECURITY
-       if (!pg_ownercheck(GetUserId(), relationName, RELNAME))
-               elog(ERROR, "ALTER TABLE: permission denied");
-#endif
-
        /*
         * Grab an exclusive lock on the target table, which we will NOT
         * release until end of transaction.
         */
        rel = heap_openr(relationName, AccessExclusiveLock);
+       myrelid = RelationGetRelid(rel);
 
        if (rel->rd_rel->relkind != RELKIND_RELATION)
                elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table",
                         relationName);
 
-       myrelid = RelationGetRelid(rel);
+       if (!allowSystemTableMods && IsSystemRelationName(relationName))
+               elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog",
+                        relationName);
+       if (!pg_class_ownercheck(myrelid, GetUserId()))
+               elog(ERROR, "ALTER TABLE: permission denied");
 
        if (inh)
        {
@@ -1496,16 +1486,9 @@ AlterTableDropConstraint(const char *relationName,
                                                 int behavior)
 {
        Relation        rel;
+       Oid                     myrelid;
        int                     deleted;
 
-       if (!allowSystemTableMods && IsSystemRelationName(relationName))
-               elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog",
-                        relationName);
-#ifndef NO_SECURITY
-       if (!pg_ownercheck(GetUserId(), relationName, RELNAME))
-               elog(ERROR, "ALTER TABLE: permission denied");
-#endif
-
        /*
         * We don't support CASCADE yet  - in fact, RESTRICT doesn't work to
         * the spec either!
@@ -1517,14 +1500,20 @@ AlterTableDropConstraint(const char *relationName,
         * Acquire an exclusive lock on the target relation for the duration
         * of the operation.
         */
-
        rel = heap_openr(relationName, AccessExclusiveLock);
+       myrelid = RelationGetRelid(rel);
 
        /* Disallow DROP CONSTRAINT on views, indexes, sequences, etc */
        if (rel->rd_rel->relkind != RELKIND_RELATION)
                elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table",
                         relationName);
 
+       if (!allowSystemTableMods && IsSystemRelationName(relationName))
+               elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog",
+                        relationName);
+       if (!pg_class_ownercheck(myrelid, GetUserId()))
+               elog(ERROR, "ALTER TABLE: permission denied");
+
        /*
         * Since all we have is the name of the constraint, we have to look
         * through all catalogs that could possibly contain a constraint for
@@ -1692,25 +1681,19 @@ AlterTableCreateToastTable(const char *relationName, bool silent)
        IndexInfo  *indexInfo;
        Oid                     classObjectId[2];
 
-       /*
-        * permissions checking.  XXX exactly what is appropriate here?
-        */
-#ifndef NO_SECURITY
-       if (!pg_ownercheck(GetUserId(), relationName, RELNAME))
-               elog(ERROR, "ALTER TABLE: permission denied");
-#endif
-
        /*
         * Grab an exclusive lock on the target table, which we will NOT
         * release until end of transaction.
         */
        rel = heap_openr(relationName, AccessExclusiveLock);
+       myrelid = RelationGetRelid(rel);
 
        if (rel->rd_rel->relkind != RELKIND_RELATION)
                elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table",
                         relationName);
 
-       myrelid = RelationGetRelid(rel);
+       if (!pg_class_ownercheck(myrelid, GetUserId()))
+               elog(ERROR, "ALTER TABLE: permission denied");
 
        /*
         * lock the pg_class tuple for update (is that really needed?)
@@ -1940,20 +1923,32 @@ LockTableCommand(LockStmt *lockstmt)
        {
                RangeVar   *relation = lfirst(p);
                char       *relname = relation->relname;
+               Oid                     reloid;
                int                     aclresult;
                Relation        rel;
 
+               /*
+                * We don't want to open the relation until we've checked privilege.
+                * So, manually get the relation OID.
+                */
+               reloid = GetSysCacheOid(RELNAME,
+                                                               PointerGetDatum(relname),
+                                                               0, 0, 0);
+               if (!OidIsValid(reloid))
+                       elog(ERROR, "LOCK TABLE: relation \"%s\" does not exist",
+                                relname);
+
                if (lockstmt->mode == AccessShareLock)
-                       aclresult = pg_aclcheck(relname, GetUserId(),
-                                                                       ACL_SELECT);
+                       aclresult = pg_class_aclcheck(reloid, GetUserId(),
+                                                                                 ACL_SELECT);
                else
-                       aclresult = pg_aclcheck(relname, GetUserId(),
-                                                                       ACL_UPDATE | ACL_DELETE);
+                       aclresult = pg_class_aclcheck(reloid, GetUserId(),
+                                                                                 ACL_UPDATE | ACL_DELETE);
 
                if (aclresult != ACLCHECK_OK)
                        elog(ERROR, "LOCK TABLE: permission denied");
 
-               rel = relation_openr(relname, lockstmt->mode);
+               rel = relation_open(reloid, lockstmt->mode);
 
                /* Currently, we only allow plain tables to be locked */
                if (rel->rd_rel->relkind != RELKIND_RELATION)
index baeff0c172d240032826b5b81f269a74ad59b8c4..4ad49581629c3acc67151959959323192a62ad81 100644 (file)
@@ -7,7 +7,7 @@
  * Copyright (c) 1999-2001, PostgreSQL Global Development Group
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.35 2001/11/02 16:30:29 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.36 2002/03/21 23:27:20 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -21,6 +21,7 @@
 #include "catalog/pg_database.h"
 #include "catalog/pg_description.h"
 #include "catalog/pg_operator.h"
+#include "catalog/pg_rewrite.h"
 #include "catalog/pg_trigger.h"
 #include "catalog/pg_type.h"
 #include "commands/comment.h"
@@ -326,11 +327,6 @@ CommentRelation(int reltype, char *relname, char *comment)
 {
        Relation        relation;
 
-       /* First, check object security */
-
-       if (!pg_ownercheck(GetUserId(), relname, RELNAME))
-               elog(ERROR, "you are not permitted to comment on class '%s'", relname);
-
        /*
         * Open the relation.  We do this mainly to acquire a lock that
         * ensures no one else drops the relation before we commit.  (If they
@@ -339,6 +335,10 @@ CommentRelation(int reltype, char *relname, char *comment)
         */
        relation = relation_openr(relname, AccessShareLock);
 
+       /* Check object security */
+       if (!pg_class_ownercheck(RelationGetRelid(relation), GetUserId()))
+               elog(ERROR, "you are not permitted to comment on class '%s'", relname);
+
        /* Next, verify that the relation type matches the intent */
 
        switch (reltype)
@@ -387,15 +387,15 @@ CommentAttribute(char *relname, char *attrname, char *comment)
        Relation        relation;
        AttrNumber      attnum;
 
-       /* First, check object security */
-
-       if (!pg_ownercheck(GetUserId(), relname, RELNAME))
-               elog(ERROR, "you are not permitted to comment on class '%s'", relname);
-
        /* Open the containing relation to ensure it won't go away meanwhile */
 
        relation = heap_openr(relname, AccessShareLock);
 
+       /* Check object security */
+
+       if (!pg_class_ownercheck(RelationGetRelid(relation), GetUserId()))
+               elog(ERROR, "you are not permitted to comment on class '%s'", relname);
+
        /* Now, fetch the attribute number from the system cache */
 
        attnum = get_attnum(RelationGetRelid(relation), attrname);
@@ -476,27 +476,32 @@ CommentDatabase(char *database, char *comment)
 static void
 CommentRewrite(char *rule, char *comment)
 {
-       Oid                     oid;
+       HeapTuple       tuple;
+       Oid                     reloid;
+       Oid                     ruleoid;
        Oid                     classoid;
-       char       *relation;
-       int                     aclcheck;
+       int32           aclcheck;
+
+       /* Find the rule's pg_rewrite tuple, get its OID and its table's OID */
+
+       tuple = SearchSysCache(RULENAME,
+                                                  PointerGetDatum(rule),
+                                                  0, 0, 0);
+       if (!HeapTupleIsValid(tuple))
+               elog(ERROR, "rule '%s' does not exist", rule);
+
+       reloid = ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_class;
+       ruleoid = tuple->t_data->t_oid;
 
-       /* First, validate user */
+       ReleaseSysCache(tuple);
 
-       relation = RewriteGetRuleEventRel(rule);
-       aclcheck = pg_aclcheck(relation, GetUserId(), ACL_RULE);
+       /* Check object security */
+
+       aclcheck = pg_class_aclcheck(reloid, GetUserId(), ACL_RULE);
        if (aclcheck != ACLCHECK_OK)
                elog(ERROR, "you are not permitted to comment on rule '%s'",
                         rule);
 
-       /* Next, find the rule's oid */
-
-       oid = GetSysCacheOid(RULENAME,
-                                                PointerGetDatum(rule),
-                                                0, 0, 0);
-       if (!OidIsValid(oid))
-               elog(ERROR, "rule '%s' does not exist", rule);
-
        /* pg_rewrite doesn't have a hard-coded OID, so must look it up */
 
        classoid = GetSysCacheOid(RELNAME,
@@ -506,7 +511,7 @@ CommentRewrite(char *rule, char *comment)
 
        /* Call CreateComments() to create/drop the comments */
 
-       CreateComments(oid, classoid, 0, comment);
+       CreateComments(ruleoid, classoid, 0, comment);
 }
 
 /*------------------------------------------------------------------
@@ -525,13 +530,7 @@ CommentType(char *type, char *comment)
 {
        Oid                     oid;
 
-       /* First, validate user */
-
-       if (!pg_ownercheck(GetUserId(), type, TYPENAME))
-               elog(ERROR, "you are not permitted to comment on type '%s'",
-                        type);
-
-       /* Next, find the type's oid */
+       /* Find the type's oid */
 
        oid = GetSysCacheOid(TYPENAME,
                                                 PointerGetDatum(type),
@@ -539,6 +538,12 @@ CommentType(char *type, char *comment)
        if (!OidIsValid(oid))
                elog(ERROR, "type '%s' does not exist", type);
 
+       /* Check object security */
+
+       if (!pg_type_ownercheck(oid, GetUserId()))
+               elog(ERROR, "you are not permitted to comment on type '%s'",
+                        type);
+
        /* Call CreateComments() to create/drop the comments */
 
        CreateComments(oid, RelOid_pg_type, 0, comment);
@@ -576,9 +581,18 @@ CommentAggregate(char *aggregate, List *arguments, char *comment)
        else
                baseoid = InvalidOid;
 
+       /* Now, attempt to find the actual tuple in pg_aggregate */
+
+       oid = GetSysCacheOid(AGGNAME,
+                                                PointerGetDatum(aggregate),
+                                                ObjectIdGetDatum(baseoid),
+                                                0, 0);
+       if (!OidIsValid(oid))
+               agg_error("CommentAggregate", aggregate, baseoid);
+
        /* Next, validate the user's attempt to comment */
 
-       if (!pg_aggr_ownercheck(GetUserId(), aggregate, baseoid))
+       if (!pg_aggr_ownercheck(oid, GetUserId()))
        {
                if (baseoid == InvalidOid)
                        elog(ERROR, "you are not permitted to comment on aggregate '%s' for all types",
@@ -588,15 +602,6 @@ CommentAggregate(char *aggregate, List *arguments, char *comment)
                                 aggregate, format_type_be(baseoid));
        }
 
-       /* Now, attempt to find the actual tuple in pg_aggregate */
-
-       oid = GetSysCacheOid(AGGNAME,
-                                                PointerGetDatum(aggregate),
-                                                ObjectIdGetDatum(baseoid),
-                                                0, 0);
-       if (!OidIsValid(oid))
-               agg_error("CommentAggregate", aggregate, baseoid);
-
        /* pg_aggregate doesn't have a hard-coded OID, so must look it up */
 
        classoid = GetSysCacheOid(RELNAME,
@@ -654,12 +659,6 @@ CommentProc(char *function, List *arguments, char *comment)
                }
        }
 
-       /* Now, validate the user's ability to comment on this function */
-
-       if (!pg_func_ownercheck(GetUserId(), function, argcount, argoids))
-               elog(ERROR, "you are not permitted to comment on function '%s'",
-                        function);
-
        /* Now, find the corresponding oid for this procedure */
 
        oid = GetSysCacheOid(PROCNAME,
@@ -670,6 +669,12 @@ CommentProc(char *function, List *arguments, char *comment)
        if (!OidIsValid(oid))
                func_error("CommentProc", function, argcount, argoids, NULL);
 
+       /* Now, validate the user's ability to comment on this function */
+
+       if (!pg_proc_ownercheck(oid, GetUserId()))
+               elog(ERROR, "you are not permitted to comment on function '%s'",
+                        function);
+
        /* Call CreateComments() to create/drop the comments */
 
        CreateComments(oid, RelOid_pg_proc, 0, comment);
@@ -757,7 +762,7 @@ CommentOperator(char *opername, List *arguments, char *comment)
 
        /* Valid user's ability to comment on this operator */
 
-       if (!pg_oper_ownercheck(GetUserId(), oid))
+       if (!pg_oper_ownercheck(oid, GetUserId()))
                elog(ERROR, "you are not permitted to comment on operator '%s'",
                         opername);
 
@@ -798,13 +803,14 @@ CommentTrigger(char *trigger, char *relname, char *comment)
 
        /* First, validate the user's action */
 
-       if (!pg_ownercheck(GetUserId(), relname, RELNAME))
+       relation = heap_openr(relname, AccessShareLock);
+
+       if (!pg_class_ownercheck(RelationGetRelid(relation), GetUserId()))
                elog(ERROR, "you are not permitted to comment on trigger '%s' %s '%s'",
                         trigger, "defined for relation", relname);
 
-       /* Now, fetch the trigger oid from pg_trigger  */
+       /* Fetch the trigger oid from pg_trigger  */
 
-       relation = heap_openr(relname, AccessShareLock);
        pg_trigger = heap_openr(TriggerRelationName, AccessShareLock);
        ScanKeyEntryInitialize(&entry[0], 0x0, Anum_pg_trigger_tgrelid,
                                                   F_OIDEQ,
index 541f3d0a484d3ed1de8978d106bb46728801e372..fc4f80468cdd6db2b953c294b8e468fd9af87ddd 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.150 2002/03/06 06:09:30 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.151 2002/03/21 23:27:20 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -266,16 +266,20 @@ DoCopy(char *relname, bool binary, bool oids, bool from, bool pipe,
        FILE       *fp;
        Relation        rel;
        const AclMode required_access = (from ? ACL_INSERT : ACL_SELECT);
-       int                     result;
+       int32           aclresult;
 
        /*
         * Open and lock the relation, using the appropriate lock type.
         */
        rel = heap_openr(relname, (from ? RowExclusiveLock : AccessShareLock));
 
-       result = pg_aclcheck(relname, GetUserId(), required_access);
-       if (result != ACLCHECK_OK)
-               elog(ERROR, "%s: %s", relname, aclcheck_error_strings[result]);
+       /* Check permissions. */
+       aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(),
+                                                                 required_access);
+       if (aclresult != ACLCHECK_OK)
+               elog(ERROR, "%s: %s",
+                        RelationGetRelationName(rel),
+                        aclcheck_error_strings[aclresult]);
        if (!pipe && !superuser())
                elog(ERROR, "You must have Postgres superuser privilege to do a COPY "
                         "directly to or from a file.  Anyone can COPY to stdout or "
index 04854a2afa1a481bb933d1564e6d4e4e36eca0d8..91f5d14a37a591f0f1c26866dbd5acd4fb93e15b 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.89 2002/03/21 16:00:31 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/commands/Attic/creatinh.c,v 1.90 2002/03/21 23:27:20 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -247,13 +247,6 @@ TruncateRelation(const char *relname)
 
        AssertArg(relname);
 
-       if (!allowSystemTableMods && IsSystemRelationName(relname))
-               elog(ERROR, "TRUNCATE cannot be used on system tables. '%s' is a system table",
-                        relname);
-
-       if (!pg_ownercheck(GetUserId(), relname, RELNAME))
-               elog(ERROR, "you do not own relation \"%s\"", relname);
-
        /* Grab exclusive lock in preparation for truncate */
        rel = heap_openr(relname, AccessExclusiveLock);
 
@@ -265,6 +258,13 @@ TruncateRelation(const char *relname)
                elog(ERROR, "TRUNCATE cannot be used on views. '%s' is a view",
                         relname);
 
+       if (!allowSystemTableMods && IsSystemRelationName(relname))
+               elog(ERROR, "TRUNCATE cannot be used on system tables. '%s' is a system table",
+                        relname);
+
+       if (!pg_class_ownercheck(RelationGetRelid(rel), GetUserId()))
+               elog(ERROR, "you do not own relation \"%s\"", relname);
+
        /* Keep the lock until transaction commit */
        heap_close(rel, NoLock);
 
@@ -458,7 +458,7 @@ MergeAttributes(List *schema, List *supers, bool istemp,
                 * We should have an UNDER permission flag for this, but for now,
                 * demand that creator of a child table own the parent.
                 */
-               if (!pg_ownercheck(GetUserId(), name, RELNAME))
+               if (!pg_class_ownercheck(RelationGetRelid(relation), GetUserId()))
                        elog(ERROR, "you do not own table \"%s\"", name);
 
                parentOids = lappendi(parentOids, relation->rd_id);
index 99b243ed4fdf9f2cfe8266ff5fd6f73c5d72f095..0dbadd95779e1b8257ca7eeebee26fcc226537ef 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/commands/Attic/remove.c,v 1.70 2002/03/20 19:43:49 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/commands/Attic/remove.c,v 1.71 2002/03/21 23:27:21 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -84,7 +84,7 @@ RemoveOperator(char *operatorName,            /* operator name */
 
        if (HeapTupleIsValid(tup))
        {
-               if (!pg_oper_ownercheck(GetUserId(), tup->t_data->t_oid))
+               if (!pg_oper_ownercheck(tup->t_data->t_oid, GetUserId()))
                        elog(ERROR, "RemoveOperator: operator '%s': permission denied",
                                 operatorName);
 
@@ -92,7 +92,6 @@ RemoveOperator(char *operatorName,            /* operator name */
                DeleteComments(tup->t_data->t_oid, RelationGetRelid(relation));
 
                simple_heap_delete(relation, &tup->t_self);
-
        }
        else
        {
@@ -242,10 +241,6 @@ RemoveType(char *typeName)         /* type name to be removed */
        HeapTuple       tup;
        char       *shadow_type;
 
-       if (!pg_ownercheck(GetUserId(), typeName, TYPENAME))
-               elog(ERROR, "RemoveType: type '%s': permission denied",
-                        typeName);
-
        relation = heap_openr(TypeRelationName, RowExclusiveLock);
 
        tup = SearchSysCache(TYPENAME,
@@ -254,6 +249,10 @@ RemoveType(char *typeName)         /* type name to be removed */
        if (!HeapTupleIsValid(tup))
                elog(ERROR, "RemoveType: type '%s' does not exist", typeName);
 
+       if (!pg_type_ownercheck(tup->t_data->t_oid, GetUserId()))
+               elog(ERROR, "RemoveType: type '%s': permission denied",
+                        typeName);
+
        /* Delete any comments associated with this type */
        DeleteComments(tup->t_data->t_oid, RelationGetRelid(relation));
 
@@ -288,10 +287,9 @@ RemoveDomain(char *domainName, int behavior)
        HeapTuple       tup;
        char            typtype;
 
-       /* Domains are stored as types.  Check for permissions on the type */
-       if (!pg_ownercheck(GetUserId(), domainName, TYPENAME))
-               elog(ERROR, "RemoveDomain: type '%s': permission denied",
-                        domainName);
+       /* CASCADE unsupported */
+       if (behavior == CASCADE)
+               elog(ERROR, "DROP DOMAIN does not support the CASCADE keyword");
 
        relation = heap_openr(TypeRelationName, RowExclusiveLock);
 
@@ -301,17 +299,16 @@ RemoveDomain(char *domainName, int behavior)
        if (!HeapTupleIsValid(tup))
                elog(ERROR, "RemoveType: type '%s' does not exist", domainName);
 
+       if (!pg_type_ownercheck(tup->t_data->t_oid, GetUserId()))
+               elog(ERROR, "RemoveDomain: type '%s': permission denied",
+                        domainName);
+
        /* Check that this is actually a domain */
        typtype = ((Form_pg_type) GETSTRUCT(tup))->typtype;
 
        if (typtype != 'd')
                elog(ERROR, "%s is not a domain", domainName);
 
-       /* CASCADE unsupported */
-       if (behavior == CASCADE) {
-               elog(ERROR, "DROP DOMAIN does not support the CASCADE keyword");
-       }
-
        /* Delete any comments associated with this type */
        DeleteComments(tup->t_data->t_oid, RelationGetRelid(relation));
 
@@ -364,12 +361,6 @@ RemoveFunction(char *functionName,         /* function name to be removed */
                }
        }
 
-       if (!pg_func_ownercheck(GetUserId(), functionName, nargs, argList))
-       {
-               elog(ERROR, "RemoveFunction: function '%s': permission denied",
-                        functionName);
-       }
-
        relation = heap_openr(ProcedureRelationName, RowExclusiveLock);
 
        tup = SearchSysCache(PROCNAME,
@@ -381,6 +372,10 @@ RemoveFunction(char *functionName,         /* function name to be removed */
        if (!HeapTupleIsValid(tup))
                func_error("RemoveFunction", functionName, nargs, argList, NULL);
 
+       if (!pg_proc_ownercheck(tup->t_data->t_oid, GetUserId()))
+               elog(ERROR, "RemoveFunction: function '%s': permission denied",
+                        functionName);
+
        if (((Form_pg_proc) GETSTRUCT(tup))->prolang == INTERNALlanguageId)
        {
                /* "Helpful" WARNING when removing a builtin function ... */
@@ -423,16 +418,6 @@ RemoveAggregate(char *aggName, char *aggType)
        else
                basetypeID = InvalidOid;
 
-       if (!pg_aggr_ownercheck(GetUserId(), aggName, basetypeID))
-       {
-               if (basetypeID == InvalidOid)
-                       elog(ERROR, "RemoveAggregate: aggregate '%s' for all types: permission denied",
-                                aggName);
-               else
-                       elog(ERROR, "RemoveAggregate: aggregate '%s' for type %s: permission denied",
-                                aggName, format_type_be(basetypeID));
-       }
-
        relation = heap_openr(AggregateRelationName, RowExclusiveLock);
 
        tup = SearchSysCache(AGGNAME,
@@ -443,6 +428,16 @@ RemoveAggregate(char *aggName, char *aggType)
        if (!HeapTupleIsValid(tup))
                agg_error("RemoveAggregate", aggName, basetypeID);
 
+       if (!pg_aggr_ownercheck(tup->t_data->t_oid, GetUserId()))
+       {
+               if (basetypeID == InvalidOid)
+                       elog(ERROR, "RemoveAggregate: aggregate '%s' for all types: permission denied",
+                                aggName);
+               else
+                       elog(ERROR, "RemoveAggregate: aggregate '%s' for type %s: permission denied",
+                                aggName, format_type_be(basetypeID));
+       }
+
        /* Remove any comments related to this aggregate */
        DeleteComments(tup->t_data->t_oid, RelationGetRelid(relation));
 
index 308808c220232d308a32858c2d6e0f49463af3c0..0ce475303a7c0092c378fbe1339833106d814bf1 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/commands/Attic/rename.c,v 1.63 2001/11/12 01:34:50 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/commands/Attic/rename.c,v 1.64 2002/03/21 23:27:21 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -81,6 +81,13 @@ renameatt(char *relname,
        List       *indexoidlist;
        List       *indexoidscan;
 
+       /*
+        * Grab an exclusive lock on the target table, which we will NOT
+        * release until end of transaction.
+        */
+       targetrelation = heap_openr(relname, AccessExclusiveLock);
+       relid = RelationGetRelid(targetrelation);
+
        /*
         * permissions checking.  this would normally be done in utility.c,
         * but this particular routine is recursive.
@@ -90,18 +97,10 @@ renameatt(char *relname,
        if (!allowSystemTableMods && IsSystemRelationName(relname))
                elog(ERROR, "renameatt: class \"%s\" is a system catalog",
                         relname);
-       if (!IsBootstrapProcessingMode() &&
-               !pg_ownercheck(GetUserId(), relname, RELNAME))
+       if (!pg_class_ownercheck(relid, GetUserId()))
                elog(ERROR, "renameatt: you do not own class \"%s\"",
                         relname);
 
-       /*
-        * Grab an exclusive lock on the target table, which we will NOT
-        * release until end of transaction.
-        */
-       targetrelation = heap_openr(relname, AccessExclusiveLock);
-       relid = RelationGetRelid(targetrelation);
-
        /*
         * if the 'recurse' flag is set then we are supposed to rename this
         * attribute in all classes that inherit from 'relname' (as well as in
index e9df6392bc083591565d106dd0f4c4f70f80adb4..5bcf4f8232794d1484168480f32bf7a0500084f0 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/commands/sequence.c,v 1.72 2002/03/21 16:00:33 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/commands/sequence.c,v 1.73 2002/03/21 23:27:21 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -299,13 +299,13 @@ nextval(PG_FUNCTION_ARGS)
                                rescnt = 0;
        bool            logit = false;
 
-       if (pg_aclcheck(seqname, GetUserId(), ACL_UPDATE) != ACLCHECK_OK)
-               elog(ERROR, "%s.nextval: you don't have permissions to set sequence %s",
-                        seqname, seqname);
-
        /* open and AccessShareLock sequence */
        elm = init_sequence("nextval", seqname);
 
+       if (pg_class_aclcheck(elm->relid, GetUserId(), ACL_UPDATE) != ACLCHECK_OK)
+               elog(ERROR, "%s.nextval: you don't have permissions to set sequence %s",
+                        seqname, seqname);
+
        pfree(seqname);
 
        if (elm->last != elm->cached)           /* some numbers were cached */
@@ -466,13 +466,13 @@ currval(PG_FUNCTION_ARGS)
        SeqTable        elm;
        int64           result;
 
-       if (pg_aclcheck(seqname, GetUserId(), ACL_SELECT) != ACLCHECK_OK)
-               elog(ERROR, "%s.currval: you don't have permissions to read sequence %s",
-                        seqname, seqname);
-
        /* open and AccessShareLock sequence */
        elm = init_sequence("currval", seqname);
 
+       if (pg_class_aclcheck(elm->relid, GetUserId(), ACL_SELECT) != ACLCHECK_OK)
+               elog(ERROR, "%s.currval: you don't have permissions to read sequence %s",
+                        seqname, seqname);
+
        if (elm->increment == 0)        /* nextval/read_info were not called */
                elog(ERROR, "%s.currval is not yet defined in this session",
                         seqname);
@@ -504,14 +504,15 @@ do_setval(char *seqname, int64 next, bool iscalled)
        Buffer          buf;
        Form_pg_sequence seq;
 
-       if (pg_aclcheck(seqname, GetUserId(), ACL_UPDATE) != ACLCHECK_OK)
+       /* open and AccessShareLock sequence */
+       elm = init_sequence("setval", seqname);
+
+       if (pg_class_aclcheck(elm->relid, GetUserId(), ACL_UPDATE) != ACLCHECK_OK)
                elog(ERROR, "%s.setval: you don't have permissions to set sequence %s",
                         seqname, seqname);
 
-       /* open and AccessShareLock sequence */
-       elm = init_sequence("setval", seqname);
-       seq = read_info("setval", elm, &buf);           /* lock page' buffer and
-                                                                                                * read tuple */
+       /* lock page' buffer and read tuple */
+       seq = read_info("setval", elm, &buf);
 
        if ((next < seq->min_value) || (next > seq->max_value))
                elog(ERROR, "%s.setval: value " INT64_FORMAT " is out of bounds (" INT64_FORMAT "," INT64_FORMAT ")",
index 5bef86e30610ce1f69a01242c4e5cf8c63f632cc..2fa17612e37616c05a4b90720f49b7874703bd89 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.106 2002/03/21 16:00:34 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.107 2002/03/21 23:27:22 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -71,12 +71,18 @@ CreateTrigger(CreateTrigStmt *stmt)
        char       *constrname = "";
        Oid                     constrrelid = InvalidOid;
 
+       rel = heap_openr(stmt->relation->relname, AccessExclusiveLock);
+
+       if (rel->rd_rel->relkind != RELKIND_RELATION)
+               elog(ERROR, "CreateTrigger: relation \"%s\" is not a table",
+                        stmt->relation->relname);
+
        if (!allowSystemTableMods && IsSystemRelationName(stmt->relation->relname))
                elog(ERROR, "CreateTrigger: can't create trigger for system relation %s",
                        stmt->relation->relname);
 
-       if (pg_aclcheck(stmt->relation->relname, GetUserId(),
-                                       stmt->isconstraint ? ACL_REFERENCES : ACL_TRIGGER)
+       if (pg_class_aclcheck(RelationGetRelid(rel), GetUserId(),
+                                                 stmt->isconstraint ? ACL_REFERENCES : ACL_TRIGGER)
                != ACLCHECK_OK)
                elog(ERROR, "permission denied");
 
@@ -98,18 +104,14 @@ CreateTrigger(CreateTrigStmt *stmt)
                         * NoLock is probably sufficient here, since we're only
                         * interested in getting the relation's OID...
                         */
-                       rel = heap_openr(stmt->constrrel->relname, NoLock);
-                       constrrelid = rel->rd_id;
-                       heap_close(rel, NoLock);
+                       Relation        conrel;
+
+                       conrel = heap_openr(stmt->constrrel->relname, NoLock);
+                       constrrelid = conrel->rd_id;
+                       heap_close(conrel, NoLock);
                }
        }
 
-       rel = heap_openr(stmt->relation->relname, AccessExclusiveLock);
-
-       if (rel->rd_rel->relkind != RELKIND_RELATION)
-               elog(ERROR, "CreateTrigger: relation \"%s\" is not a table",
-                        stmt->relation->relname);
-
        TRIGGER_CLEAR_TYPE(tgtype);
        if (stmt->before)
                TRIGGER_SETT_BEFORE(tgtype);
@@ -321,20 +323,20 @@ DropTrigger(DropTrigStmt *stmt)
        int                     found = 0;
        int                     tgfound = 0;
 
+       rel = heap_openr(stmt->relation->relname, AccessExclusiveLock);
+
+       if (rel->rd_rel->relkind != RELKIND_RELATION)
+               elog(ERROR, "DropTrigger: relation \"%s\" is not a table",
+                        stmt->relation->relname);
+
        if (!allowSystemTableMods && IsSystemRelationName(stmt->relation->relname))
                elog(ERROR, "DropTrigger: can't drop trigger for system relation %s",
                         stmt->relation->relname);
 
-       if (!pg_ownercheck(GetUserId(), stmt->relation->relname, RELNAME))
+       if (!pg_class_ownercheck(RelationGetRelid(rel), GetUserId()))
                elog(ERROR, "%s: %s", stmt->relation->relname,
                         aclcheck_error_strings[ACLCHECK_NOT_OWNER]);
 
-       rel = heap_openr(stmt->relation->relname, AccessExclusiveLock);
-
-       if (rel->rd_rel->relkind != RELKIND_RELATION)
-               elog(ERROR, "DropTrigger: relation \"%s\" is not a table",
-                        stmt->relation->relname);
-
        /*
         * Search pg_trigger, delete target trigger, count remaining triggers
         * for relation.  Note this is OK only because we have
index 836091c583f45224f2834e0079ad666006e48733..41405f3654a9220c0d27f3a88d8843fdae2d9104 100644 (file)
@@ -13,7 +13,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.218 2002/03/21 16:00:35 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.219 2002/03/21 23:27:22 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -714,15 +714,14 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt)
         *
         * We allow the user to vacuum a table if he is superuser, the table
         * owner, or the database owner (but in the latter case, only if it's
-        * not a shared relation).      pg_ownercheck includes the superuser case.
+        * not a shared relation).      pg_class_ownercheck includes the superuser case.
         *
         * Note we choose to treat permissions failure as a WARNING and keep
         * trying to vacuum the rest of the DB --- is this appropriate?
         */
        onerel = heap_open(relid, lmode);
 
-       if (!(pg_ownercheck(GetUserId(), RelationGetRelationName(onerel),
-                                               RELNAME) ||
+       if (!(pg_class_ownercheck(RelationGetRelid(onerel), GetUserId()) ||
                  (is_dbadmin(MyDatabaseId) && !onerel->rd_rel->relisshared)))
        {
                elog(WARNING, "Skipping \"%s\" --- only table or database owner can VACUUM it",
index 9b8e3586024178765e8ff7621f941193d882b713..8532da15975a3ab22f9b6a95c3ba1300b7b31046 100644 (file)
@@ -27,7 +27,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.153 2002/03/21 16:00:37 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.154 2002/03/21 23:27:23 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -43,6 +43,7 @@
 #include "optimizer/var.h"
 #include "parser/parsetree.h"
 #include "utils/acl.h"
+#include "utils/lsyscache.h"
 
 
 /* decls for local routines only used within this module */
@@ -355,7 +356,7 @@ ExecCheckRTPerms(List *rangeTable, CmdType operation)
 static void
 ExecCheckRTEPerms(RangeTblEntry *rte, CmdType operation)
 {
-       char       *relName;
+       Oid                     relOid;
        Oid                     userid;
        int32           aclcheck_result;
 
@@ -363,10 +364,10 @@ ExecCheckRTEPerms(RangeTblEntry *rte, CmdType operation)
         * If it's a subquery RTE, ignore it --- it will be checked when
         * ExecCheckPlanPerms finds the SubqueryScan node for it.
         */
-       if (rte->subquery)
+       if (rte->rtekind != RTE_RELATION)
                return;
 
-       relName = rte->relname;
+       relOid = rte->relid;
 
        /*
         * userid to check as: current user unless we have a setuid
@@ -379,14 +380,15 @@ ExecCheckRTEPerms(RangeTblEntry *rte, CmdType operation)
         */
        userid = rte->checkAsUser ? rte->checkAsUser : GetUserId();
 
-#define CHECK(MODE)            pg_aclcheck(relName, userid, MODE)
+#define CHECK(MODE)            pg_class_aclcheck(relOid, userid, MODE)
 
        if (rte->checkForRead)
        {
                aclcheck_result = CHECK(ACL_SELECT);
                if (aclcheck_result != ACLCHECK_OK)
                        elog(ERROR, "%s: %s",
-                                relName, aclcheck_error_strings[aclcheck_result]);
+                                get_rel_name(relOid),
+                                aclcheck_error_strings[aclcheck_result]);
        }
 
        if (rte->checkForWrite)
@@ -416,7 +418,8 @@ ExecCheckRTEPerms(RangeTblEntry *rte, CmdType operation)
                }
                if (aclcheck_result != ACLCHECK_OK)
                        elog(ERROR, "%s: %s",
-                                relName, aclcheck_error_strings[aclcheck_result]);
+                                get_rel_name(relOid),
+                                aclcheck_error_strings[aclcheck_result]);
        }
 }
 
index 0b47aa9c924593f07d064566102d384c5929651e..7e9f0fcfbb350e7113f15364db23f351fab2e2df 100644 (file)
@@ -8,11 +8,10 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteDefine.c,v 1.64 2002/03/21 16:01:16 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteDefine.c,v 1.65 2002/03/21 23:27:23 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
-
 #include "postgres.h"
 
 #include "access/heapam.h"
@@ -27,6 +26,7 @@
 #include "rewrite/rewriteManip.h"
 #include "rewrite/rewriteSupport.h"
 #include "storage/smgr.h"
+#include "utils/acl.h"
 #include "utils/builtins.h"
 #include "utils/syscache.h"
 
@@ -127,6 +127,7 @@ DefineQueryRewrite(RuleStmt *stmt)
                           *event_qualP;
        List       *l;
        Query      *query;
+       int32           aclcheck_result;
        bool            RelisBecomingView = false;
 
        /*
@@ -140,6 +141,15 @@ DefineQueryRewrite(RuleStmt *stmt)
        event_relation = heap_openr(event_obj->relname, AccessExclusiveLock);
        ev_relid = RelationGetRelid(event_relation);
 
+       /*
+        * Check user has permission to apply rules to this relation.
+        */
+       aclcheck_result = pg_class_aclcheck(ev_relid, GetUserId(), ACL_RULE);
+       if (aclcheck_result != ACLCHECK_OK)
+               elog(ERROR, "%s: %s",
+                        RelationGetRelationName(event_relation),
+                        aclcheck_error_strings[aclcheck_result]);
+
        /*
         * No rule actions that modify OLD or NEW
         */
index 92326d93b6dc8ccf8e8936f12ac0f579ae51f729..6d251b78343416bcd01164c62ab0d6fb552c113a 100644 (file)
@@ -8,12 +8,10 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteRemove.c,v 1.45 2001/08/10 18:57:37 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteRemove.c,v 1.46 2002/03/21 23:27:23 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
-
-
 #include "postgres.h"
 
 #include "utils/builtins.h"
 #include "catalog/catname.h"
 #include "catalog/pg_rewrite.h"
 #include "commands/comment.h"
+#include "miscadmin.h"
 #include "rewrite/rewriteRemove.h"
 #include "rewrite/rewriteSupport.h"
+#include "utils/acl.h"
 #include "utils/fmgroids.h"
 #include "utils/syscache.h"
 
-/*-----------------------------------------------------------------------
- * RewriteGetRuleEventRel
- *-----------------------------------------------------------------------
- */
-char *
-RewriteGetRuleEventRel(char *rulename)
-{
-       HeapTuple       htup;
-       Oid                     eventrel;
-       char       *result;
-
-       htup = SearchSysCache(RULENAME,
-                                                 PointerGetDatum(rulename),
-                                                 0, 0, 0);
-       if (!HeapTupleIsValid(htup))
-               elog(ERROR, "Rule or view \"%s\" not found",
-                        ((strncmp(rulename, "_RET", 4) == 0) ? (rulename + 4) : rulename));
-       eventrel = ((Form_pg_rewrite) GETSTRUCT(htup))->ev_class;
-       ReleaseSysCache(htup);
-
-       htup = SearchSysCache(RELOID,
-                                                 PointerGetDatum(eventrel),
-                                                 0, 0, 0);
-       if (!HeapTupleIsValid(htup))
-               elog(ERROR, "Relation %u not found", eventrel);
-
-       result = pstrdup(NameStr(((Form_pg_class) GETSTRUCT(htup))->relname));
-       ReleaseSysCache(htup);
-       return result;
-}
 
 /*
  * RemoveRewriteRule
@@ -71,6 +41,7 @@ RemoveRewriteRule(char *ruleName)
        Oid                     ruleId;
        Oid                     eventRelationOid;
        bool            hasMoreRules;
+       int32           aclcheck_result;
 
        /*
         * Open the pg_rewrite relation.
@@ -88,10 +59,7 @@ RemoveRewriteRule(char *ruleName)
         * complain if no rule with such name existed
         */
        if (!HeapTupleIsValid(tuple))
-       {
-               heap_close(RewriteRelation, RowExclusiveLock);
                elog(ERROR, "Rule \"%s\" not found", ruleName);
-       }
 
        /*
         * Save the OID of the rule (i.e. the tuple's OID) and the event
@@ -108,6 +76,16 @@ RemoveRewriteRule(char *ruleName)
         */
        event_relation = heap_open(eventRelationOid, AccessExclusiveLock);
 
+       /*
+        * Verify user has appropriate permissions.
+        */
+       aclcheck_result = pg_class_aclcheck(eventRelationOid, GetUserId(),
+                                                                               ACL_RULE);
+       if (aclcheck_result != ACLCHECK_OK)
+               elog(ERROR, "%s: %s",
+                        RelationGetRelationName(event_relation),
+                        aclcheck_error_strings[aclcheck_result]);
+
        /* do not allow the removal of a view's SELECT rule */
        if (event_relation->rd_rel->relkind == RELKIND_VIEW &&
                ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_type == '1')
index 9a6813635cac0e1771bb920d3937ef80acfde837..1f0046887f429a3a250b46c1431cf5bb337338a9 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.136 2002/03/21 16:01:30 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.137 2002/03/21 23:27:23 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -116,7 +116,7 @@ CheckDropPermissions(char *name, char rightkind)
        if (classform->relkind != rightkind)
                DropErrorMsg(name, classform->relkind, rightkind);
 
-       if (!pg_ownercheck(GetUserId(), name, RELNAME))
+       if (!pg_class_ownercheck(tuple->t_data->t_oid, GetUserId()))
                elog(ERROR, "you do not own %s \"%s\"",
                         rentry->name, name);
 
@@ -128,6 +128,31 @@ CheckDropPermissions(char *name, char rightkind)
        ReleaseSysCache(tuple);
 }
 
+static void
+CheckOwnership(char *relname, bool noCatalogs)
+{
+       HeapTuple       tuple;
+
+       tuple = SearchSysCache(RELNAME,
+                                                  PointerGetDatum(relname),
+                                                  0, 0, 0);
+       if (!HeapTupleIsValid(tuple))
+               elog(ERROR, "Relation \"%s\" does not exist", relname);
+
+       if (!pg_class_ownercheck(tuple->t_data->t_oid, GetUserId()))
+               elog(ERROR, "%s: %s", relname,
+                        aclcheck_error_strings[ACLCHECK_NOT_OWNER]);
+
+       if (noCatalogs)
+       {
+               if (!allowSystemTableMods && IsSystemRelationName(relname))
+                       elog(ERROR, "relation \"%s\" is a system catalog",
+                                relname);
+       }
+
+       ReleaseSysCache(tuple);
+}
+
 
 /*
  * ProcessUtility
@@ -149,7 +174,6 @@ ProcessUtility(Node *parsetree,
                           char *completionTag)
 {
        char       *relname;
-       char       *relationName;
 
        if (completionTag)
                completionTag[0] = '\0';
@@ -271,17 +295,8 @@ ProcessUtility(Node *parsetree,
                                                        break;
 
                                                case DROP_RULE:
-                                                       {
-                                                               char       *rulename = relname;
-                                                               int                     aclcheck_result;
-
-                                                               relationName = RewriteGetRuleEventRel(rulename);
-                                                               aclcheck_result = pg_aclcheck(relationName, GetUserId(), ACL_RULE);
-                                                               if (aclcheck_result != ACLCHECK_OK)
-                                                                       elog(ERROR, "%s: %s", relationName,
-                                                                                aclcheck_error_strings[aclcheck_result]);
-                                                               RemoveRewriteRule(rulename);
-                                                       }
+                                                       /* RemoveRewriteRule checks permissions */
+                                                       RemoveRewriteRule(relname);
                                                        break;
 
                                                case DROP_TYPE:
@@ -355,11 +370,7 @@ ProcessUtility(Node *parsetree,
                                RenameStmt *stmt = (RenameStmt *) parsetree;
 
                                relname = stmt->relation->relname;
-                               if (!allowSystemTableMods && IsSystemRelationName(relname))
-                                       elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog",
-                                                relname);
-                               if (!pg_ownercheck(GetUserId(), relname, RELNAME))
-                                       elog(ERROR, "permission denied");
+                               CheckOwnership(relname, true);
 
                                /* ----------------
                                 *      XXX using len == 3 to tell the difference
@@ -509,11 +520,7 @@ ProcessUtility(Node *parsetree,
                                IndexStmt  *stmt = (IndexStmt *) parsetree;
 
                                relname = stmt->relation->relname;
-                               if (!allowSystemTableMods && IsSystemRelationName(relname))
-                                       elog(ERROR, "CREATE INDEX: relation \"%s\" is a system catalog",
-                                                relname);
-                               if (!pg_ownercheck(GetUserId(), relname, RELNAME))
-                                       elog(ERROR, "permission denied");
+                               CheckOwnership(relname, true);
 
                                DefineIndex(stmt->relation->relname,    /* relation */
                                                        stmt->idxname,                          /* index name */
@@ -527,17 +534,7 @@ ProcessUtility(Node *parsetree,
                        break;
 
                case T_RuleStmt:                /* CREATE RULE */
-                       {
-                               RuleStmt   *stmt = (RuleStmt *) parsetree;
-                               int                     aclcheck_result;
-
-                               relname = stmt->relation->relname;
-                               aclcheck_result = pg_aclcheck(relname, GetUserId(), ACL_RULE);
-                               if (aclcheck_result != ACLCHECK_OK)
-                                       elog(ERROR, "%s: %s", relname, aclcheck_error_strings[aclcheck_result]);
-
-                               DefineQueryRewrite(stmt);
-                       }
+                       DefineQueryRewrite((RuleStmt *) parsetree);
                        break;
 
                case T_CreateSeqStmt:
@@ -646,11 +643,7 @@ ProcessUtility(Node *parsetree,
                                ClusterStmt *stmt = (ClusterStmt *) parsetree;
 
                                relname = stmt->relation->relname;
-                               if (IsSystemRelationName(relname))
-                                       elog(ERROR, "CLUSTER: relation \"%s\" is a system catalog",
-                                                relname);
-                               if (!pg_ownercheck(GetUserId(), relname, RELNAME))
-                                       elog(ERROR, "permission denied");
+                               CheckOwnership(relname, true);
 
                                cluster(relname, stmt->indexname);
                        }
@@ -790,14 +783,12 @@ ProcessUtility(Node *parsetree,
                                                                elog(ERROR, "\"%s\" is a system index. call REINDEX under standalone postgres with -P -O options",
                                                                         relname);
                                                }
-                                               if (!pg_ownercheck(GetUserId(), relname, RELNAME))
-                                                       elog(ERROR, "%s: %s", relname, aclcheck_error_strings[ACLCHECK_NOT_OWNER]);
+                                               CheckOwnership(relname, false);
                                                ReindexIndex(relname, stmt->force);
                                                break;
                                        case TABLE:
                                                relname = (char *) stmt->relation->relname;
-                                               if (!pg_ownercheck(GetUserId(), relname, RELNAME))
-                                                       elog(ERROR, "%s: %s", relname, aclcheck_error_strings[ACLCHECK_NOT_OWNER]);
+                                               CheckOwnership(relname, false);
                                                ReindexTable(relname, stmt->force);
                                                break;
                                        case DATABASE:
index f868b36861d8260f3e54dc206144b544f3868c84..0e73cb04b10d7504a4e803b937c9387ce24201b2 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.68 2002/03/02 21:39:32 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.69 2002/03/21 23:27:24 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -817,30 +817,21 @@ has_table_privilege_id(PG_FUNCTION_ARGS)
 {
        Oid                     reloid = PG_GETARG_OID(0);
        text       *priv_type_text = PG_GETARG_TEXT_P(1);
-       char       *relname;
        int32           usesysid;
        AclMode         mode;
        int32           result;
 
        usesysid = GetUserId();
 
-       /*
-        * Lookup relname based on rel oid
-        */
-       relname = get_rel_name(reloid);
-       if (relname == NULL)
-               elog(ERROR, "has_table_privilege: invalid relation oid %u",
-                        reloid);
-
        /*
         * Convert priv_type_text to an AclMode
         */
        mode = convert_priv_string(priv_type_text);
 
        /*
-        * Finally, check for the privilege
+        * Check for the privilege
         */
-       result = pg_aclcheck(relname, usesysid, mode);
+       result = pg_class_aclcheck(reloid, usesysid, mode);
 
        if (result == ACLCHECK_OK)
                PG_RETURN_BOOL(true);
@@ -891,27 +882,18 @@ has_table_privilege_id_id(PG_FUNCTION_ARGS)
        int32           usesysid = PG_GETARG_INT32(0);
        Oid                     reloid = PG_GETARG_OID(1);
        text       *priv_type_text = PG_GETARG_TEXT_P(2);
-       char       *relname;
        AclMode         mode;
        int32           result;
 
-       /*
-        * Lookup relname based on rel oid
-        */
-       relname = get_rel_name(reloid);
-       if (relname == NULL)
-               elog(ERROR, "has_table_privilege: invalid relation oid %u",
-                        reloid);
-
        /*
         * Convert priv_type_text to an AclMode
         */
        mode = convert_priv_string(priv_type_text);
 
        /*
-        * Finally, check for the privilege
+        * Check for the privilege
         */
-       result = pg_aclcheck(relname, usesysid, mode);
+       result = pg_class_aclcheck(reloid, usesysid, mode);
 
        if (result == ACLCHECK_OK)
                PG_RETURN_BOOL(true);
@@ -1050,22 +1032,19 @@ static bool
 has_table_privilege_id_cname(int32 usesysid, char *relname,
                                                         text *priv_type_text)
 {
-       HeapTuple       tuple;
+       Oid                     reloid;
        AclMode         mode;
        int32           result;
 
        /*
-        * Check relname is valid. This is needed to deal with the case when
-        * usename is a superuser in which case pg_aclcheck simply returns
-        * ACLCHECK_OK without validating relname
+        * Convert relname to rel OID.
         */
-       tuple = SearchSysCache(RELNAME,
-                                                  PointerGetDatum(relname),
-                                                  0, 0, 0);
-       if (!HeapTupleIsValid(tuple))
+       reloid = GetSysCacheOid(RELNAME,
+                                                       PointerGetDatum(relname),
+                                                       0, 0, 0);
+       if (!OidIsValid(reloid))
                elog(ERROR, "has_table_privilege: relation \"%s\" does not exist",
                         relname);
-       ReleaseSysCache(tuple);
 
        /*
         * Convert priv_type_text to an AclMode
@@ -1075,7 +1054,7 @@ has_table_privilege_id_cname(int32 usesysid, char *relname,
        /*
         * Finally, check for the privilege
         */
-       result = pg_aclcheck(relname, usesysid, mode);
+       result = pg_class_aclcheck(reloid, usesysid, mode);
 
        if (result == ACLCHECK_OK)
                return true;
index dfbcccffbed250efda87862838f135fc11c352cb..8779125d1591d4554ee0c9c8809626df6dd1b6de 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.67 2002/02/19 20:11:18 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.68 2002/03/21 23:27:24 tgl Exp $
  *
  * NOTES
  *       These routines allow the parser/planner/executor to perform
@@ -103,6 +103,16 @@ static struct cachedesc cacheinfo[] = {
                        0,
                        0
        }},
+       {AggregateRelationName,         /* AGGOID */
+               AggregateOidIndex,
+               0,
+               1,
+               {
+                       ObjectIdAttributeNumber,
+                       0,
+                       0,
+                       0
+       }},
        {AccessMethodRelationName,      /* AMNAME */
                AmNameIndex,
                0,
index 672ed7f85d880629f67eba6724813c8e31459153..ccfc2dbb12bb76c4e8d1e2f471d9a7a1abe2ef97 100644 (file)
@@ -7,14 +7,13 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: rewriteRemove.h,v 1.10 2001/11/05 17:46:35 momjian Exp $
+ * $Id: rewriteRemove.h,v 1.11 2002/03/21 23:27:24 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 #ifndef REWRITEREMOVE_H
 #define REWRITEREMOVE_H
 
-extern char *RewriteGetRuleEventRel(char *rulename);
 extern void RemoveRewriteRule(char *ruleName);
 extern void RelationRemoveRules(Oid relid);
 
index 3619797151b68e10728cc1b51f856d50bf476b9c..2a862af4bdd06cedf1b54191c8afa53dacfb7e20 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: acl.h,v 1.40 2002/02/18 23:11:45 petere Exp $
+ * $Id: acl.h,v 1.41 2002/03/21 23:27:25 tgl Exp $
  *
  * NOTES
  *       For backward-compatibility purposes we have to allow there
 
 #include "nodes/parsenodes.h"
 #include "utils/array.h"
-#include "utils/memutils.h"
+
 
 /*
  * AclId               system identifier for the user, group, etc.
- *                             XXX currently UNIX uid for users...
+ *                             XXX Perhaps replace this type by OID?
  */
 typedef uint32 AclId;
 
@@ -159,14 +159,14 @@ typedef ArrayType IdList;
 #define ACL_MODE_REFERENCES_CHR 'x'
 #define ACL_MODE_TRIGGER_CHR   't'
 
-/* result codes for pg_aclcheck */
+/* result codes for pg_*_aclcheck */
 #define ACLCHECK_OK                              0
 #define ACLCHECK_NO_PRIV                 1
 #define ACLCHECK_NO_CLASS                2
 #define ACLCHECK_NOT_OWNER               3
 
-/* error messages (index by ACL_CHECK_* result code).  set in aclchk.c. */
-extern char *aclcheck_error_strings[];
+/* error messages (index by ACLCHECK_* result code).  set in aclchk.c. */
+extern const char * const aclcheck_error_strings[];
 
 /*
  * routines used internally
@@ -199,16 +199,16 @@ extern void ExecuteGrantStmt(GrantStmt *stmt);
 extern AclId get_grosysid(char *groname);
 extern char *get_groname(AclId grosysid);
 
-extern int32 pg_aclcheck(char *relname, Oid userid, AclMode mode);
-
-extern bool pg_ownercheck(Oid userid, const char *name, int cacheid);
-extern bool pg_oper_ownercheck(Oid userid, Oid oprid);
-extern bool pg_func_ownercheck(Oid userid, char *funcname,
-                                  int nargs, Oid *arglist);
-extern bool pg_aggr_ownercheck(Oid userid, char *aggname,
-                                  Oid basetypeID);
-
+/* these return ACLCHECK_* result codes */
+extern int32 pg_class_aclcheck(Oid table_oid, Oid userid, AclMode mode);
 extern int32 pg_proc_aclcheck(Oid proc_oid, Oid userid);
 extern int32 pg_language_aclcheck(Oid lang_oid, Oid userid);
 
+/* ownercheck routines just return true (owner) or false (not) */
+extern bool pg_class_ownercheck(Oid class_oid, Oid userid);
+extern bool pg_type_ownercheck(Oid type_oid, Oid userid);
+extern bool pg_oper_ownercheck(Oid oper_oid, Oid userid);
+extern bool pg_proc_ownercheck(Oid proc_oid, Oid userid);
+extern bool pg_aggr_ownercheck(Oid aggr_oid, Oid userid);
+
 #endif   /* ACL_H */
index 6164c02b1525e6320b545250f39518e9a16f82e2..d4bcd14256e1fd9650bace2110f6f2d1edc68fe4 100644 (file)
@@ -9,7 +9,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: syscache.h,v 1.37 2002/02/19 20:11:20 tgl Exp $
+ * $Id: syscache.h,v 1.38 2002/03/21 23:27:25 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
  */
 
 #define AGGNAME                        0
-#define AMNAME                 1
-#define AMOID                  2
-#define AMOPOPID               3
-#define AMOPSTRATEGY   4
-#define AMPROCNUM              5
-#define ATTNAME                        6
-#define ATTNUM                 7
-#define CLAAMNAME              8
-#define CLAOID                 9
-#define GRONAME                        10
-#define GROSYSID               11
-#define INDEXRELID             12
-#define INHRELID               13
-#define LANGNAME               14
-#define LANGOID                        15
-#define OPERNAME               16
-#define OPEROID                        17
-#define PROCNAME               18
-#define PROCOID                        19
-#define RELNAME                        20
-#define RELOID                 21
-#define RULENAME               22
-#define SHADOWNAME             23
-#define SHADOWSYSID            24
-#define STATRELATT             25
-#define TYPENAME               26
-#define TYPEOID                        27
+#define AGGOID                 1
+#define AMNAME                 2
+#define AMOID                  3
+#define AMOPOPID               4
+#define AMOPSTRATEGY   5
+#define AMPROCNUM              6
+#define ATTNAME                        7
+#define ATTNUM                 8
+#define CLAAMNAME              9
+#define CLAOID                 10
+#define GRONAME                        11
+#define GROSYSID               12
+#define INDEXRELID             13
+#define INHRELID               14
+#define LANGNAME               15
+#define LANGOID                        16
+#define OPERNAME               17
+#define OPEROID                        18
+#define PROCNAME               19
+#define PROCOID                        20
+#define RELNAME                        21
+#define RELOID                 22
+#define RULENAME               23
+#define SHADOWNAME             24
+#define SHADOWSYSID            25
+#define STATRELATT             26
+#define TYPENAME               27
+#define TYPEOID                        28
+
 
 extern void InitCatalogCache(void);
 extern void InitCatalogCachePhase2(void);
index 625c6d7499d8ac8f3585e37cf016ad00a35c3f05..bd9707c2bdbeeb07e734cd35c97ca55885c9516f 100644 (file)
@@ -221,7 +221,7 @@ drop rule 314159;
 ERROR:  parser: parse error at or near "314159"
 -- no such rule 
 drop rule nonesuch;
-ERROR:  Rule or view "nonesuch" not found
+ERROR:  Rule "nonesuch" not found
 -- bad keyword 
 drop tuple rule nonesuch;
 ERROR:  parser: parse error at or near "tuple"
index 0bf560a949f8f932e1c9fd0dab3a9e21f0453c06..6c9b84dda2b8f56a4d63deec162b66c41300679d 100644 (file)
@@ -90,7 +90,7 @@ ERROR:  LOCK TABLE: permission denied
 COPY atest2 FROM stdin; -- fail
 ERROR:  atest2: Permission denied.
 GRANT ALL ON atest1 TO PUBLIC; -- fail
-ERROR:  permission denied
+ERROR:  atest1: permission denied
 -- checks in subquery, both ok
 SELECT * FROM atest1 WHERE ( b IN ( SELECT col1 FROM atest2 ) );
  a | b 
@@ -246,9 +246,9 @@ ERROR:  user "nosuchuser" does not exist
 select has_table_privilege('pg_shadow','sel');
 ERROR:  has_table_privilege: invalid privilege type sel
 select has_table_privilege(-999999,'pg_shadow','update');
-ERROR:  pg_aclcheck: invalid user id 4293967297
+ERROR:  pg_class_aclcheck: invalid user id 4293967297
 select has_table_privilege(1,'rule');
-ERROR:  has_table_privilege: invalid relation oid 1
+ERROR:  pg_class_aclcheck: relation 1 not found
 -- superuser
 \c -
 select has_table_privilege(current_user,'pg_shadow','select');