]> granicus.if.org Git - postgresql/commitdiff
Correct permissions-checking bugs associated with ancient decision to
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 5 Jun 2001 19:34:56 +0000 (19:34 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 5 Jun 2001 19:34:56 +0000 (19:34 +0000)
copy PUBLIC access rights into each newly created ACL entry.  Instead
treat each ACL entry as independent flags.  Also clean up some ugliness
in acl.h API.

src/backend/catalog/aclchk.c
src/backend/commands/comment.c
src/backend/commands/remove.c
src/backend/utils/adt/acl.c
src/include/utils/acl.h

index 5ef74cb1d557a670d8b2e7b9fda65a6104b64249..f772ea3a534696718581ce8de6de1cf7833c0bd2 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.48 2001/05/27 09:59:28 petere Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.49 2001/06/05 19:34:56 tgl Exp $
  *
  * NOTES
  *       See acl.h.
@@ -33,8 +33,7 @@
 #include "utils/acl.h"
 #include "utils/syscache.h"
 
-static int32 aclcheck(char *relname, Acl *acl, AclId id,
-                AclIdType idtype, AclMode mode);
+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. */
@@ -192,6 +191,9 @@ get_groname(AclId grosysid)
        return name;
 }
 
+/*
+ * Is user a member of group?
+ */
 static bool
 in_group(AclId uid, AclId gid)
 {
@@ -199,7 +201,7 @@ in_group(AclId uid, AclId gid)
        HeapTuple       tuple;
        Datum           att;
        bool            isNull;
-       IdList     *tmp;
+       IdList     *glist;
        AclId      *aidp;
        int                     i,
                                num;
@@ -216,10 +218,10 @@ in_group(AclId uid, AclId gid)
                if (!isNull)
                {
                        /* be sure the IdList is not toasted */
-                       tmp = DatumGetIdListP(att);
+                       glist = DatumGetIdListP(att);
                        /* scan it */
-                       num = IDLIST_NUM(tmp);
-                       aidp = IDLIST_DAT(tmp);
+                       num = IDLIST_NUM(glist);
+                       aidp = IDLIST_DAT(glist);
                        for (i = 0; i < num; ++i)
                        {
                                if (aidp[i] == uid)
@@ -228,6 +230,9 @@ in_group(AclId uid, AclId gid)
                                        break;
                                }
                        }
+                       /* if IdList was toasted, free detoasted copy */
+                       if ((Pointer) glist != DatumGetPointer(att))
+                               pfree(glist);
                }
                ReleaseSysCache(tuple);
        }
@@ -238,11 +243,15 @@ in_group(AclId uid, AclId gid)
 
 /*
  * aclcheck
- * Returns 1 if the 'id' of type 'idtype' has ACL entries in 'acl' to satisfy
- * any one of the requirements of 'mode'.  Returns 0 otherwise.
+ *
+ * Returns ACLCHECK_OK if the 'id' of type 'idtype' has ACL entries in 'acl'
+ * to satisfy any one of the requirements of 'mode'.  Returns an appropriate
+ * ACLCHECK_* error code otherwise.
+ *
+ * The ACL list is expected to be sorted in standard order.
  */
 static int32
-aclcheck(char *relname, Acl *acl, AclId id, AclIdType idtype, AclMode mode)
+aclcheck(Acl *acl, AclId id, AclIdType idtype, AclMode mode)
 {
        AclItem    *aip,
                           *aidat;
@@ -255,7 +264,7 @@ aclcheck(char *relname, Acl *acl, AclId id, AclIdType idtype, AclMode mode)
         */
        if (!acl)
        {
-               elog(DEBUG, "aclcheck: null ACL, returning 1");
+               elog(DEBUG, "aclcheck: null ACL, returning OK");
                return ACLCHECK_OK;
        }
 
@@ -270,15 +279,28 @@ aclcheck(char *relname, Acl *acl, AclId id, AclIdType idtype, AclMode mode)
         */
        if (num < 1)
        {
-               elog(DEBUG, "aclcheck: zero-length ACL, returning 1");
+               elog(DEBUG, "aclcheck: zero-length ACL, returning OK");
+               return ACLCHECK_OK;
+       }
+
+       /*
+        * "World" rights are applicable regardless of the passed-in ID,
+        * and since they're much the cheapest to check, check 'em first.
+        */
+       if (aidat->ai_idtype != ACL_IDTYPE_WORLD)
+               elog(ERROR, "aclcheck: first entry in ACL is not 'world' entry");
+       if (aidat->ai_mode & mode)
+       {
+#ifdef ACLDEBUG
+               elog(DEBUG, "aclcheck: using world=%d", aidat->ai_mode);
+#endif
                return ACLCHECK_OK;
        }
-       Assert(aidat->ai_idtype == ACL_IDTYPE_WORLD);
 
        switch (idtype)
        {
                case ACL_IDTYPE_UID:
-                       /* Look for exact match to user */
+                       /* See if permission is granted directly to user */
                        for (i = 1, aip = aidat + 1;            /* skip world entry */
                                 i < num && aip->ai_idtype == ACL_IDTYPE_UID;
                                 ++i, ++aip)
@@ -289,7 +311,8 @@ aclcheck(char *relname, Acl *acl, AclId id, AclIdType idtype, AclMode mode)
                                        elog(DEBUG, "aclcheck: found user %u/%d",
                                                 aip->ai_id, aip->ai_mode);
 #endif
-                                       return (aip->ai_mode & mode) ? ACLCHECK_OK : ACLCHECK_NO_PRIV;
+                                       if (aip->ai_mode & mode)
+                                               return ACLCHECK_OK;
                                }
                        }
                        /* See if he has the permission via any group */
@@ -309,15 +332,13 @@ aclcheck(char *relname, Acl *acl, AclId id, AclIdType idtype, AclMode mode)
                                        }
                                }
                        }
-                       /* Else, look to the world entry */
                        break;
                case ACL_IDTYPE_GID:
                        /* Look for this group ID */
-                       for (i = 1, aip = aidat + 1;            /* skip world entry and
-                                                                                                * UIDs */
+                       for (i = 1, aip = aidat + 1;            /* skip world entry */
                                 i < num && aip->ai_idtype == ACL_IDTYPE_UID;
                                 ++i, ++aip)
-                               ;
+                               /* skip UID entry */;
                        for (;
                                 i < num && aip->ai_idtype == ACL_IDTYPE_GID;
                                 ++i, ++aip)
@@ -328,10 +349,10 @@ aclcheck(char *relname, Acl *acl, AclId id, AclIdType idtype, AclMode mode)
                                        elog(DEBUG, "aclcheck: found group %u/%d",
                                                 aip->ai_id, aip->ai_mode);
 #endif
-                                       return (aip->ai_mode & mode) ? ACLCHECK_OK : ACLCHECK_NO_PRIV;
+                                       if (aip->ai_mode & mode)
+                                               return ACLCHECK_OK;
                                }
                        }
-                       /* Else, look to the world entry */
                        break;
                case ACL_IDTYPE_WORLD:
                        /* Only check the world entry */
@@ -341,12 +362,15 @@ aclcheck(char *relname, Acl *acl, AclId id, AclIdType idtype, AclMode mode)
                        break;
        }
 
-#ifdef ACLDEBUG
-       elog(DEBUG, "aclcheck: using world=%d", aidat->ai_mode);
-#endif
-       return (aidat->ai_mode & mode) ? ACLCHECK_OK : ACLCHECK_NO_PRIV;
+       /* If get here, he doesn't have the privilege nohow */
+       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)
 {
@@ -357,6 +381,9 @@ pg_aclcheck(char *relname, Oid userid, AclMode mode)
        bool            isNull;
        Acl                *acl;
 
+       /*
+        * Validate userid, find out if he is superuser
+        */
        tuple = SearchSysCache(SHADOWSYSID,
                                                   ObjectIdGetDatum(userid),
                                                   0, 0, 0);
@@ -371,13 +398,15 @@ pg_aclcheck(char *relname, Oid userid, AclMode mode)
         * pg_shadow.usecatupd is set.  (This is to let superusers protect
         * themselves from themselves.)
         */
-       if (((mode & ACL_UPDATE) || (mode & ACL_INSERT) || (mode & ACL_DELETE)) &&
+       if ((mode & (ACL_INSERT | ACL_UPDATE | ACL_DELETE)) &&
                !allowSystemTableMods && IsSystemRelationName(relname) &&
                strncmp(relname, "pg_temp.", strlen("pg_temp.")) != 0 &&
                !((Form_pg_shadow) GETSTRUCT(tuple))->usecatupd)
        {
+#ifdef ACLDEBUG
                elog(DEBUG, "pg_aclcheck: catalog update to \"%s\": permission denied",
                         relname);
+#endif
                ReleaseSysCache(tuple);
                return ACLCHECK_NO_PRIV;
        }
@@ -416,25 +445,35 @@ pg_aclcheck(char *relname, Oid userid, AclMode mode)
 
                ownerId = ((Form_pg_class) GETSTRUCT(tuple))->relowner;
                acl = acldefault(relname, ownerId);
+               aclDatum = (Datum) 0;
        }
        else
        {
-               /* get a detoasted copy of the rel's ACL */
-               acl = DatumGetAclPCopy(aclDatum);
+               /* detoast rel's ACL if necessary */
+               acl = DatumGetAclP(aclDatum);
        }
 
-       result = aclcheck(relname, acl, userid, (AclIdType) ACL_IDTYPE_UID, mode);
+       result = aclcheck(acl, userid, (AclIdType) ACL_IDTYPE_UID, mode);
 
-       if (acl)
+       /* if we have a detoasted copy, free it */
+       if (acl && (Pointer) acl != DatumGetPointer(aclDatum))
                pfree(acl);
+
        ReleaseSysCache(tuple);
 
        return result;
 }
 
-int32
+/*
+ * 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 *value,
+                         const char *name,
                          int cacheid)
 {
        HeapTuple       tuple;
@@ -459,39 +498,27 @@ pg_ownercheck(Oid userid,
                         usename);
 #endif
                ReleaseSysCache(tuple);
-               return 1;
+               return true;
        }
 
        ReleaseSysCache(tuple);
        /* caution: usename is inaccessible beyond this point... */
 
        tuple = SearchSysCache(cacheid,
-                                                  PointerGetDatum(value),
+                                                  PointerGetDatum(name),
                                                   0, 0, 0);
        switch (cacheid)
        {
-               case OPEROID:
-                       if (!HeapTupleIsValid(tuple))
-                               elog(ERROR, "pg_ownercheck: operator %ld not found",
-                                        PointerGetDatum(value));
-                       owner_id = ((Form_pg_operator) GETSTRUCT(tuple))->oprowner;
-                       break;
-               case PROCNAME:
-                       if (!HeapTupleIsValid(tuple))
-                               elog(ERROR, "pg_ownercheck: function \"%s\" not found",
-                                        value);
-                       owner_id = ((Form_pg_proc) GETSTRUCT(tuple))->proowner;
-                       break;
                case RELNAME:
                        if (!HeapTupleIsValid(tuple))
                                elog(ERROR, "pg_ownercheck: class \"%s\" not found",
-                                        value);
+                                        name);
                        owner_id = ((Form_pg_class) GETSTRUCT(tuple))->relowner;
                        break;
                case TYPENAME:
                        if (!HeapTupleIsValid(tuple))
                                elog(ERROR, "pg_ownercheck: type \"%s\" not found",
-                                        value);
+                                        name);
                        owner_id = ((Form_pg_type) GETSTRUCT(tuple))->typowner;
                        break;
                default:
@@ -505,7 +532,58 @@ pg_ownercheck(Oid userid,
        return userid == owner_id;
 }
 
-int32
+/*
+ * 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(DEBUG, "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,
@@ -533,7 +611,7 @@ pg_func_ownercheck(Oid userid,
                         usename);
 #endif
                ReleaseSysCache(tuple);
-               return 1;
+               return true;
        }
 
        ReleaseSysCache(tuple);
@@ -554,7 +632,11 @@ pg_func_ownercheck(Oid userid,
        return userid == owner_id;
 }
 
-int32
+/*
+ * Ownership check for an aggregate function (specified by name and
+ * argument type).
+ */
+bool
 pg_aggr_ownercheck(Oid userid,
                                   char *aggname,
                                   Oid basetypeID)
@@ -581,7 +663,7 @@ pg_aggr_ownercheck(Oid userid,
                         usename);
 #endif
                ReleaseSysCache(tuple);
-               return 1;
+               return true;
        }
 
        ReleaseSysCache(tuple);
index 7d3ba9b5618c607e949678524d4b55b51b3210bd..695c7401e719cdf499ab2e475d375b99080b7dbb 100644 (file)
@@ -7,7 +7,7 @@
  * Copyright (c) 1999, PostgreSQL Global Development Group
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.28 2001/05/27 09:59:29 petere Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.29 2001/06/05 19:34:56 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -507,13 +507,9 @@ CommentType(char *type, char *comment)
 
        /*** First, validate user ***/
 
-#ifndef NO_SECURITY
        if (!pg_ownercheck(GetUserId(), type, TYPENAME))
-       {
                elog(ERROR, "you are not permitted to comment on type '%s'",
                         type);
-       }
-#endif
 
        /*** Next, find the type's oid ***/
 
@@ -561,21 +557,15 @@ CommentAggregate(char *aggregate, List *arguments, char *comment)
 
        /*** Next, validate the user's attempt to comment ***/
 
-#ifndef NO_SECURITY
        if (!pg_aggr_ownercheck(GetUserId(), aggregate, baseoid))
        {
                if (aggtypename)
-               {
                        elog(ERROR, "you are not permitted to comment on aggregate '%s' %s '%s'",
                                 aggregate, "with type", aggtypename);
-               }
                else
-               {
                        elog(ERROR, "you are not permitted to comment on aggregate '%s'",
                                 aggregate);
-               }
        }
-#endif
 
        /*** Now, attempt to find the actual tuple in pg_aggregate ***/
 
@@ -646,11 +636,9 @@ CommentProc(char *function, List *arguments, char *comment)
 
        /*** Now, validate the user's ability to comment on this function ***/
 
-#ifndef NO_SECURITY
        if (!pg_func_ownercheck(GetUserId(), function, argcount, argoids))
                elog(ERROR, "you are not permitted to comment on function '%s'",
                         function);
-#endif
 
        /*** Now, find the corresponding oid for this procedure ***/
 
@@ -745,13 +733,9 @@ CommentOperator(char *opername, List *arguments, char *comment)
 
        /*** Valid user's ability to comment on this operator ***/
 
-#ifndef NO_SECURITY
-       if (!pg_ownercheck(GetUserId(), (char *) ObjectIdGetDatum(oid), OPEROID))
-       {
+       if (!pg_oper_ownercheck(GetUserId(), oid))
                elog(ERROR, "you are not permitted to comment on operator '%s'",
                         opername);
-       }
-#endif
 
        /*** Get the procedure associated with the operator ***/
 
@@ -792,13 +776,9 @@ CommentTrigger(char *trigger, char *relname, char *comment)
 
        /*** First, validate the user's action ***/
 
-#ifndef NO_SECURITY
        if (!pg_ownercheck(GetUserId(), relname, RELNAME))
-       {
                elog(ERROR, "you are not permitted to comment on trigger '%s' %s '%s'",
                         trigger, "defined for relation", relname);
-       }
-#endif
 
        /*** Now, fetch the trigger oid from pg_trigger  ***/
 
index da5ad74d8ba8d544eb9be1a11d20157d9962f6e0..48701a893a812bc0f3bc43706e1d00910e948e8c 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/commands/Attic/remove.c,v 1.60 2001/03/22 03:59:23 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/commands/Attic/remove.c,v 1.61 2001/06/05 19:34:56 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -81,9 +81,7 @@ RemoveOperator(char *operatorName,            /* operator name */
 
        if (HeapTupleIsValid(tup))
        {
-               if (!pg_ownercheck(GetUserId(),
-                                                  (char *) ObjectIdGetDatum(tup->t_data->t_oid),
-                                                  OPEROID))
+               if (!pg_oper_ownercheck(GetUserId(), tup->t_data->t_oid))
                        elog(ERROR, "RemoveOperator: operator '%s': permission denied",
                                 operatorName);
 
index f4e3fe9986d809499193b08e69c5475b21103bd8..1da525bd032dd7df8f1c810582f72ac081c4f2f3 100644 (file)
@@ -8,14 +8,14 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.59 2001/05/27 09:59:30 petere Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.60 2001/06/05 19:34:56 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
-#include <ctype.h>
-
 #include "postgres.h"
 
+#include <ctype.h>
+
 #include "access/heapam.h"
 #include "catalog/catalog.h"
 #include "catalog/pg_shadow.h"
@@ -392,7 +392,8 @@ acldefault(char *relname, AclId ownerid)
 
 
 /*
- * Add or replace an item in an ACL array.
+ * Add or replace an item in an ACL array.  The result is a modified copy;
+ * the input object is not changed.
  *
  * NB: caller is responsible for having detoasted the input ACL, if needed.
  */
@@ -402,8 +403,7 @@ aclinsert3(Acl *old_acl, AclItem *mod_aip, unsigned modechg)
        Acl                *new_acl;
        AclItem    *old_aip,
                           *new_aip;
-       int                     src,
-                               dst,
+       int                     dst,
                                num;
 
        /* These checks for null input are probably dead code, but... */
@@ -431,14 +431,14 @@ aclinsert3(Acl *old_acl, AclItem *mod_aip, unsigned modechg)
 
        if (dst < num && aclitemeq(mod_aip, old_aip + dst))
        {
-               /* modify in-place */
+               /* found a match, so modify existing item */
                new_acl = makeacl(num);
                new_aip = ACL_DAT(new_acl);
                memcpy((char *) new_acl, (char *) old_acl, ACL_SIZE(old_acl));
-               src = dst;
        }
        else
        {
+               /* need to insert a new item */
                new_acl = makeacl(num + 1);
                new_aip = ACL_DAT(new_acl);
                if (dst == 0)
@@ -460,20 +460,21 @@ aclinsert3(Acl *old_acl, AclItem *mod_aip, unsigned modechg)
                                   (char *) (old_aip + dst),
                                   (num - dst) * sizeof(AclItem));
                }
+               /* initialize the new entry with no permissions */
                new_aip[dst].ai_id = mod_aip->ai_id;
                new_aip[dst].ai_idtype = mod_aip->ai_idtype;
+               new_aip[dst].ai_mode = 0;
                num++;                                  /* set num to the size of new_acl */
-               src = 0;                                /* if add or del, start from world entry */
        }
 
        /* apply the permissions mod */
        switch (modechg)
        {
                case ACL_MODECHG_ADD:
-                       new_aip[dst].ai_mode = old_aip[src].ai_mode | mod_aip->ai_mode;
+                       new_aip[dst].ai_mode |= mod_aip->ai_mode;
                        break;
                case ACL_MODECHG_DEL:
-                       new_aip[dst].ai_mode = old_aip[src].ai_mode & ~mod_aip->ai_mode;
+                       new_aip[dst].ai_mode &= ~mod_aip->ai_mode;
                        break;
                case ACL_MODECHG_EQL:
                        new_aip[dst].ai_mode = mod_aip->ai_mode;
@@ -487,16 +488,10 @@ aclinsert3(Acl *old_acl, AclItem *mod_aip, unsigned modechg)
         */
        if (new_aip[dst].ai_mode == 0 && dst > 0)
        {
-               int                     i;
-
-               for (i = dst + 1; i < num; i++)
-               {
-                       new_aip[i - 1].ai_id = new_aip[i].ai_id;
-                       new_aip[i - 1].ai_idtype = new_aip[i].ai_idtype;
-                       new_aip[i - 1].ai_mode = new_aip[i].ai_mode;
-               }
+               memmove((char *) (new_aip + dst),
+                               (char *) (new_aip + dst + 1),
+                               (num - dst - 1) * sizeof(AclItem));
                ARR_DIMS(new_acl)[0] = num - 1;
-               /* Adjust also the array size because it is used for memcpy */
                ARR_SIZE(new_acl) -= sizeof(AclItem);
        }
 
index 02e6094c51eea7570af472a1f1113a29d4bfea84..2ea98d5cb6e55a52ca84ce91e6b9500f7c9c0bce 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.32 2001/05/27 09:59:30 petere Exp $
+ * $Id: acl.h,v 1.33 2001/06/05 19:34:56 tgl Exp $
  *
  * NOTES
  *       For backward-compatibility purposes we have to allow there
@@ -164,7 +164,7 @@ typedef ArrayType IdList;
 #define ACLCHECK_NO_CLASS                2
 #define ACLCHECK_NOT_OWNER               3
 
-/* warning messages.  set these in aclchk.c. */
+/* error messages (index by ACL_CHECK_* result code).  set in aclchk.c. */
 extern char *aclcheck_error_strings[];
 
 /*
@@ -201,10 +201,12 @@ extern AclId get_grosysid(char *groname);
 extern char *get_groname(AclId grosysid);
 
 extern int32 pg_aclcheck(char *relname, Oid userid, AclMode mode);
-extern int32 pg_ownercheck(Oid userid, const char *value, int cacheid);
-extern int32 pg_func_ownercheck(Oid userid, char *funcname,
-                                  int nargs, Oid *arglist);
-extern int32 pg_aggr_ownercheck(Oid userid, char *aggname,
-                                  Oid basetypeID);
+
+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);
 
 #endif  /* ACL_H */