From 7215f74b89640f642d219b0675ef3997fc4c8fc2 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 2 Oct 2000 04:49:28 +0000 Subject: [PATCH] Make default ACL be consistent --- ie, starting point for ChangeAcl is the same as the access permissions granted when a relation's relacl field is NULL, ie, owner=all rights, world=no rights. --- src/backend/catalog/aclchk.c | 131 ++++++++++++++----------------------------- src/backend/utils/adt/acl.c | 28 +++++---- src/include/utils/acl.h | 26 ++++----- 3 files changed, 68 insertions(+), 117 deletions(-) diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c index b5c9cf51a1..a338cfb224 100644 --- a/src/backend/catalog/aclchk.c +++ b/src/backend/catalog/aclchk.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.40 2000/09/06 14:15:15 petere Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.41 2000/10/02 04:49:28 tgl Exp $ * * NOTES * See acl.h. @@ -36,28 +36,8 @@ static int32 aclcheck(char *relname, Acl *acl, AclId id, AclIdType idtype, AclMode mode); -/* - * Enable use of user relations in place of real system catalogs. - */ -/*#define ACLDEBUG*/ - -#ifdef ACLDEBUG -/* - * Fool the code below into thinking that "pgacls" is pg_class. - * relname and relowner are in the same place, happily. - */ -#undef Anum_pg_class_relacl -#define Anum_pg_class_relacl 3 -#undef Natts_pg_class -#define Natts_pg_class 3 -#undef Name_pg_class -#define Name_pg_class "pgacls" -#undef Name_pg_group -#define Name_pg_group "pggroup" -#endif - /* warning messages, now more explicit. */ -/* should correspond to the order of the ACLCHK_* result codes above. */ +/* MUST correspond to the order of the ACLCHK_* result codes in acl.h. */ char *aclcheck_error_strings[] = { "No error.", "Permission denied.", @@ -65,6 +45,7 @@ char *aclcheck_error_strings[] = { "Must be table owner." }; + #ifdef ACLDEBUG_TRACE static dumpacl(Acl *acl) @@ -84,7 +65,7 @@ dumpacl(Acl *acl) #endif /* - * + * ChangeAcl */ void ChangeAcl(char *relname, @@ -96,12 +77,12 @@ ChangeAcl(char *relname, *new_acl; Relation relation; HeapTuple tuple; + Datum aclDatum; Datum values[Natts_pg_class]; char nulls[Natts_pg_class]; char replaces[Natts_pg_class]; Relation idescs[Num_pg_class_indices]; bool isNull; - bool free_old_acl = false; /* * Find the pg_class tuple matching 'relname' and extract the ACL. If @@ -118,29 +99,20 @@ ChangeAcl(char *relname, relname); } - old_acl = (Acl *) heap_getattr(tuple, - Anum_pg_class_relacl, - RelationGetDescr(relation), - &isNull); + aclDatum = SysCacheGetAttr(RELNAME, tuple, Anum_pg_class_relacl, + &isNull); if (isNull) { -#ifdef ACLDEBUG_TRACE - elog(DEBUG, "ChangeAcl: using default ACL"); -#endif - old_acl = acldefault(relname); - free_old_acl = true; - } - - /* Need to detoast the old ACL for modification */ - old_acl = DatumGetAclP(PointerGetDatum(old_acl)); + /* No ACL, so build default ACL for rel */ + AclId ownerId; - if (ACL_NUM(old_acl) < 1) + ownerId = ((Form_pg_class) GETSTRUCT(tuple))->relowner; + old_acl = acldefault(relname, ownerId); + } + else { -#ifdef ACLDEBUG_TRACE - elog(DEBUG, "ChangeAcl: old ACL has zero length"); -#endif - old_acl = acldefault(relname); - free_old_acl = true; + /* get a detoasted copy of the rel's ACL */ + old_acl = DatumGetAclPCopy(aclDatum); } #ifdef ACLDEBUG_TRACE @@ -173,8 +145,8 @@ ChangeAcl(char *relname, CatalogCloseIndices(Num_pg_class_indices, idescs); heap_close(relation, RowExclusiveLock); - if (free_old_acl) - pfree(old_acl); + + pfree(old_acl); pfree(new_acl); } @@ -264,9 +236,15 @@ aclcheck(char *relname, Acl *acl, AclId id, AclIdType idtype, AclMode mode) unsigned num, found_group; - /* if no acl is found, use world default */ + /* + * If ACL is null, default to "OK" --- this should not happen, + * since caller should have inserted appropriate default + */ if (!acl) - acl = acldefault(relname); + { + elog(DEBUG, "aclcheck: null ACL, returning 1"); + return ACLCHECK_OK; + } num = ACL_NUM(acl); aidat = ACL_DAT(acl); @@ -278,9 +256,7 @@ aclcheck(char *relname, Acl *acl, AclId id, AclIdType idtype, AclMode mode) */ if (num < 1) { -#if defined(ACLDEBUG_TRACE) || 1 elog(DEBUG, "aclcheck: zero-length ACL, returning 1"); -#endif return ACLCHECK_OK; } @@ -357,11 +333,12 @@ aclcheck(char *relname, Acl *acl, AclId id, AclIdType idtype, AclMode mode) int32 pg_aclcheck(char *relname, Oid userid, AclMode mode) { - HeapTuple tuple; - Acl *acl = (Acl *) NULL; int32 result; + HeapTuple tuple; char *usename; - Relation relation; + Datum aclDatum; + bool isNull; + Acl *acl; tuple = SearchSysCacheTuple(SHADOWSYSID, ObjectIdGetDatum(userid), @@ -399,53 +376,31 @@ pg_aclcheck(char *relname, Oid userid, AclMode mode) return ACLCHECK_OK; } -#ifndef ACLDEBUG - relation = heap_openr(RelationRelationName, RowExclusiveLock); + /* + * Normal case: get the relation's ACL from pg_class + */ tuple = SearchSysCacheTuple(RELNAME, PointerGetDatum(relname), 0, 0, 0); if (!HeapTupleIsValid(tuple)) - { - elog(ERROR, "pg_aclcheck: class \"%s\" not found", - relname); - } - if (!heap_attisnull(tuple, Anum_pg_class_relacl)) - { - /* get a detoasted copy of the ACL */ - acl = DatumGetAclPCopy(heap_getattr(tuple, - Anum_pg_class_relacl, - RelationGetDescr(relation), - (bool *) NULL)); - } - else - { + elog(ERROR, "pg_aclcheck: class \"%s\" not found", relname); - /* - * if the acl is null, by default the owner can do whatever he - * wants to with it - */ + aclDatum = SysCacheGetAttr(RELNAME, tuple, Anum_pg_class_relacl, + &isNull); + if (isNull) + { + /* No ACL, so build default ACL for rel */ AclId ownerId; ownerId = ((Form_pg_class) GETSTRUCT(tuple))->relowner; - acl = aclownerdefault(relname, ownerId); + acl = acldefault(relname, ownerId); } - heap_close(relation, RowExclusiveLock); -#else - relation = heap_openr(RelationRelationName, RowExclusiveLock); - tuple = SearchSysCacheTuple(RELNAME, - PointerGetDatum(relname), - 0, 0, 0); - if (HeapTupleIsValid(tuple) && - !heap_attisnull(tuple, Anum_pg_class_relacl)) + else { - /* get a detoasted copy of the ACL */ - acl = DatumGetAclPCopy(heap_getattr(tuple, - Anum_pg_class_relacl, - RelationGetDescr(relation), - (bool *) NULL)); + /* get a detoasted copy of the rel's ACL */ + acl = DatumGetAclPCopy(aclDatum); } - heap_close(relation, RowExclusiveLock); -#endif + result = aclcheck(relname, acl, userid, (AclIdType) ACL_IDTYPE_UID, mode); if (acl) pfree(acl); diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c index c4f1228dbc..3d43a45cd1 100644 --- a/src/backend/utils/adt/acl.c +++ b/src/backend/utils/adt/acl.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.48 2000/07/31 22:39:09 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.49 2000/10/02 04:49:27 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -334,12 +334,23 @@ aclitemgt(AclItem *a1, AclItem *a2) (a1->ai_idtype == a2->ai_idtype && a1->ai_id > a2->ai_id)); } + +/* + * acldefault() --- create an ACL describing default access permissions + * + * Change this routine if you want to alter the default access policy for + * newly-created tables (or any table with a NULL acl entry in pg_class) + */ Acl * -aclownerdefault(char *relname, AclId ownerid) +acldefault(char *relname, AclId ownerid) { Acl *acl; AclItem *aip; +#define ACL_WORLD_DEFAULT (ACL_NO) +/* #define ACL_WORLD_DEFAULT (ACL_RD|ACL_WR|ACL_AP|ACL_RU) */ +#define ACL_OWNER_DEFAULT (ACL_RD|ACL_WR|ACL_AP|ACL_RU) + acl = makeacl(2); aip = ACL_DAT(acl); aip[0].ai_idtype = ACL_IDTYPE_WORLD; @@ -351,19 +362,6 @@ aclownerdefault(char *relname, AclId ownerid) return acl; } -Acl * -acldefault(char *relname) -{ - Acl *acl; - AclItem *aip; - - acl = makeacl(1); - aip = ACL_DAT(acl); - aip[0].ai_idtype = ACL_IDTYPE_WORLD; - aip[0].ai_id = ACL_ID_WORLD; - aip[0].ai_mode = IsSystemRelationName(relname) ? ACL_RD : ACL_WORLD_DEFAULT; - return acl; -} /* * Add or replace an item in an ACL array. diff --git a/src/include/utils/acl.h b/src/include/utils/acl.h index 5e91f56bf5..4add4202fc 100644 --- a/src/include/utils/acl.h +++ b/src/include/utils/acl.h @@ -7,12 +7,12 @@ * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: acl.h,v 1.27 2000/09/06 14:15:31 petere Exp $ + * $Id: acl.h,v 1.28 2000/10/02 04:49:27 tgl Exp $ * * NOTES * For backward-compatibility purposes we have to allow there * to be a null ACL in a pg_class tuple. This will be defined as - * meaning "no protection" (i.e., old catalogs get old semantics). + * meaning "default protection" (i.e., whatever acldefault() returns). * * The AclItems in an ACL array are currently kept in sorted order. * Things will break hard if you change that without changing the @@ -32,7 +32,7 @@ */ typedef uint32 AclId; -#define ACL_ID_WORLD 0 /* XXX only idtype should be checked */ +#define ACL_ID_WORLD 0 /* placeholder for id in a WORLD acl item */ /* * AclIdType tag that describes if the AclId is a user, group, etc. @@ -58,15 +58,6 @@ typedef uint8 AclMode; #define ACL_RU (1<<3) /* place rules */ #define N_ACL_MODES 4 -#define ACL_MODECHG_ADD 1 -#define ACL_MODECHG_DEL 2 -#define ACL_MODECHG_EQL 3 - -/* change this line if you want to set the default acl permission */ -#define ACL_WORLD_DEFAULT (ACL_NO) -/* #define ACL_WORLD_DEFAULT (ACL_RD|ACL_WR|ACL_AP|ACL_RU) */ -#define ACL_OWNER_DEFAULT (ACL_RD|ACL_WR|ACL_AP|ACL_RU) - /* * AclItem */ @@ -143,6 +134,13 @@ typedef ArrayType IdList; #define PG_RETURN_IDLIST_P(x) PG_RETURN_POINTER(x) +/* + * ACL modification opcodes + */ +#define ACL_MODECHG_ADD 1 +#define ACL_MODECHG_DEL 2 +#define ACL_MODECHG_EQL 3 + /* mode indicators for I/O */ #define ACL_MODECHG_STR "+-=" /* list of valid characters */ #define ACL_MODECHG_ADD_CHR '+' @@ -171,8 +169,8 @@ extern char *aclcheck_error_strings[]; /* * routines used internally (parser, etc.) */ -extern Acl *aclownerdefault(char *relname, AclId ownerid); -extern Acl *acldefault(char *relname); +extern Acl *acldefault(char *relname, AclId ownerid); + extern Acl *aclinsert3(Acl *old_acl, AclItem *mod_aip, unsigned modechg); extern char *aclmakepriv(char *old_privlist, char new_priv); -- 2.11.0