Commit 7215f74b authored by Tom Lane's avatar Tom Lane

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.
parent 46cf9257
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * NOTES
* See acl.h. * See acl.h.
...@@ -36,28 +36,8 @@ ...@@ -36,28 +36,8 @@
static int32 aclcheck(char *relname, Acl *acl, AclId id, static int32 aclcheck(char *relname, Acl *acl, AclId id,
AclIdType idtype, AclMode mode); 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. */ /* 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[] = { char *aclcheck_error_strings[] = {
"No error.", "No error.",
"Permission denied.", "Permission denied.",
...@@ -65,6 +45,7 @@ char *aclcheck_error_strings[] = { ...@@ -65,6 +45,7 @@ char *aclcheck_error_strings[] = {
"Must be table owner." "Must be table owner."
}; };
#ifdef ACLDEBUG_TRACE #ifdef ACLDEBUG_TRACE
static static
dumpacl(Acl *acl) dumpacl(Acl *acl)
...@@ -84,7 +65,7 @@ dumpacl(Acl *acl) ...@@ -84,7 +65,7 @@ dumpacl(Acl *acl)
#endif #endif
/* /*
* * ChangeAcl
*/ */
void void
ChangeAcl(char *relname, ChangeAcl(char *relname,
...@@ -96,12 +77,12 @@ ChangeAcl(char *relname, ...@@ -96,12 +77,12 @@ ChangeAcl(char *relname,
*new_acl; *new_acl;
Relation relation; Relation relation;
HeapTuple tuple; HeapTuple tuple;
Datum aclDatum;
Datum values[Natts_pg_class]; Datum values[Natts_pg_class];
char nulls[Natts_pg_class]; char nulls[Natts_pg_class];
char replaces[Natts_pg_class]; char replaces[Natts_pg_class];
Relation idescs[Num_pg_class_indices]; Relation idescs[Num_pg_class_indices];
bool isNull; bool isNull;
bool free_old_acl = false;
/* /*
* Find the pg_class tuple matching 'relname' and extract the ACL. If * Find the pg_class tuple matching 'relname' and extract the ACL. If
...@@ -118,29 +99,20 @@ ChangeAcl(char *relname, ...@@ -118,29 +99,20 @@ ChangeAcl(char *relname,
relname); relname);
} }
old_acl = (Acl *) heap_getattr(tuple, aclDatum = SysCacheGetAttr(RELNAME, tuple, Anum_pg_class_relacl,
Anum_pg_class_relacl, &isNull);
RelationGetDescr(relation),
&isNull);
if (isNull) if (isNull)
{ {
#ifdef ACLDEBUG_TRACE /* No ACL, so build default ACL for rel */
elog(DEBUG, "ChangeAcl: using default ACL"); AclId ownerId;
#endif
old_acl = acldefault(relname);
free_old_acl = true;
}
/* Need to detoast the old ACL for modification */
old_acl = DatumGetAclP(PointerGetDatum(old_acl));
if (ACL_NUM(old_acl) < 1) ownerId = ((Form_pg_class) GETSTRUCT(tuple))->relowner;
old_acl = acldefault(relname, ownerId);
}
else
{ {
#ifdef ACLDEBUG_TRACE /* get a detoasted copy of the rel's ACL */
elog(DEBUG, "ChangeAcl: old ACL has zero length"); old_acl = DatumGetAclPCopy(aclDatum);
#endif
old_acl = acldefault(relname);
free_old_acl = true;
} }
#ifdef ACLDEBUG_TRACE #ifdef ACLDEBUG_TRACE
...@@ -173,8 +145,8 @@ ChangeAcl(char *relname, ...@@ -173,8 +145,8 @@ ChangeAcl(char *relname,
CatalogCloseIndices(Num_pg_class_indices, idescs); CatalogCloseIndices(Num_pg_class_indices, idescs);
heap_close(relation, RowExclusiveLock); heap_close(relation, RowExclusiveLock);
if (free_old_acl)
pfree(old_acl); pfree(old_acl);
pfree(new_acl); pfree(new_acl);
} }
...@@ -264,9 +236,15 @@ aclcheck(char *relname, Acl *acl, AclId id, AclIdType idtype, AclMode mode) ...@@ -264,9 +236,15 @@ aclcheck(char *relname, Acl *acl, AclId id, AclIdType idtype, AclMode mode)
unsigned num, unsigned num,
found_group; 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) if (!acl)
acl = acldefault(relname); {
elog(DEBUG, "aclcheck: null ACL, returning 1");
return ACLCHECK_OK;
}
num = ACL_NUM(acl); num = ACL_NUM(acl);
aidat = ACL_DAT(acl); aidat = ACL_DAT(acl);
...@@ -278,9 +256,7 @@ aclcheck(char *relname, Acl *acl, AclId id, AclIdType idtype, AclMode mode) ...@@ -278,9 +256,7 @@ aclcheck(char *relname, Acl *acl, AclId id, AclIdType idtype, AclMode mode)
*/ */
if (num < 1) if (num < 1)
{ {
#if defined(ACLDEBUG_TRACE) || 1
elog(DEBUG, "aclcheck: zero-length ACL, returning 1"); elog(DEBUG, "aclcheck: zero-length ACL, returning 1");
#endif
return ACLCHECK_OK; return ACLCHECK_OK;
} }
...@@ -357,11 +333,12 @@ aclcheck(char *relname, Acl *acl, AclId id, AclIdType idtype, AclMode mode) ...@@ -357,11 +333,12 @@ aclcheck(char *relname, Acl *acl, AclId id, AclIdType idtype, AclMode mode)
int32 int32
pg_aclcheck(char *relname, Oid userid, AclMode mode) pg_aclcheck(char *relname, Oid userid, AclMode mode)
{ {
HeapTuple tuple;
Acl *acl = (Acl *) NULL;
int32 result; int32 result;
HeapTuple tuple;
char *usename; char *usename;
Relation relation; Datum aclDatum;
bool isNull;
Acl *acl;
tuple = SearchSysCacheTuple(SHADOWSYSID, tuple = SearchSysCacheTuple(SHADOWSYSID,
ObjectIdGetDatum(userid), ObjectIdGetDatum(userid),
...@@ -399,53 +376,31 @@ pg_aclcheck(char *relname, Oid userid, AclMode mode) ...@@ -399,53 +376,31 @@ pg_aclcheck(char *relname, Oid userid, AclMode mode)
return ACLCHECK_OK; return ACLCHECK_OK;
} }
#ifndef ACLDEBUG /*
relation = heap_openr(RelationRelationName, RowExclusiveLock); * Normal case: get the relation's ACL from pg_class
*/
tuple = SearchSysCacheTuple(RELNAME, tuple = SearchSysCacheTuple(RELNAME,
PointerGetDatum(relname), PointerGetDatum(relname),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
{ elog(ERROR, "pg_aclcheck: class \"%s\" not found", relname);
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
{
/* aclDatum = SysCacheGetAttr(RELNAME, tuple, Anum_pg_class_relacl,
* if the acl is null, by default the owner can do whatever he &isNull);
* wants to with it if (isNull)
*/ {
/* No ACL, so build default ACL for rel */
AclId ownerId; AclId ownerId;
ownerId = ((Form_pg_class) GETSTRUCT(tuple))->relowner; ownerId = ((Form_pg_class) GETSTRUCT(tuple))->relowner;
acl = aclownerdefault(relname, ownerId); acl = acldefault(relname, ownerId);
} }
heap_close(relation, RowExclusiveLock); else
#else
relation = heap_openr(RelationRelationName, RowExclusiveLock);
tuple = SearchSysCacheTuple(RELNAME,
PointerGetDatum(relname),
0, 0, 0);
if (HeapTupleIsValid(tuple) &&
!heap_attisnull(tuple, Anum_pg_class_relacl))
{ {
/* get a detoasted copy of the ACL */ /* get a detoasted copy of the rel's ACL */
acl = DatumGetAclPCopy(heap_getattr(tuple, acl = DatumGetAclPCopy(aclDatum);
Anum_pg_class_relacl,
RelationGetDescr(relation),
(bool *) NULL));
} }
heap_close(relation, RowExclusiveLock);
#endif
result = aclcheck(relname, acl, userid, (AclIdType) ACL_IDTYPE_UID, mode); result = aclcheck(relname, acl, userid, (AclIdType) ACL_IDTYPE_UID, mode);
if (acl) if (acl)
pfree(acl); pfree(acl);
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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) ...@@ -334,12 +334,23 @@ aclitemgt(AclItem *a1, AclItem *a2)
(a1->ai_idtype == a2->ai_idtype && a1->ai_id > a2->ai_id)); (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 * Acl *
aclownerdefault(char *relname, AclId ownerid) acldefault(char *relname, AclId ownerid)
{ {
Acl *acl; Acl *acl;
AclItem *aip; 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); acl = makeacl(2);
aip = ACL_DAT(acl); aip = ACL_DAT(acl);
aip[0].ai_idtype = ACL_IDTYPE_WORLD; aip[0].ai_idtype = ACL_IDTYPE_WORLD;
...@@ -351,19 +362,6 @@ aclownerdefault(char *relname, AclId ownerid) ...@@ -351,19 +362,6 @@ aclownerdefault(char *relname, AclId ownerid)
return acl; 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. * Add or replace an item in an ACL array.
......
...@@ -7,12 +7,12 @@ ...@@ -7,12 +7,12 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * 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 * NOTES
* For backward-compatibility purposes we have to allow there * For backward-compatibility purposes we have to allow there
* to be a null ACL in a pg_class tuple. This will be defined as * 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. * The AclItems in an ACL array are currently kept in sorted order.
* Things will break hard if you change that without changing the * Things will break hard if you change that without changing the
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
*/ */
typedef uint32 AclId; 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. * AclIdType tag that describes if the AclId is a user, group, etc.
...@@ -58,15 +58,6 @@ typedef uint8 AclMode; ...@@ -58,15 +58,6 @@ typedef uint8 AclMode;
#define ACL_RU (1<<3) /* place rules */ #define ACL_RU (1<<3) /* place rules */
#define N_ACL_MODES 4 #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 * AclItem
*/ */
...@@ -143,6 +134,13 @@ typedef ArrayType IdList; ...@@ -143,6 +134,13 @@ typedef ArrayType IdList;
#define PG_RETURN_IDLIST_P(x) PG_RETURN_POINTER(x) #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 */ /* mode indicators for I/O */
#define ACL_MODECHG_STR "+-=" /* list of valid characters */ #define ACL_MODECHG_STR "+-=" /* list of valid characters */
#define ACL_MODECHG_ADD_CHR '+' #define ACL_MODECHG_ADD_CHR '+'
...@@ -171,8 +169,8 @@ extern char *aclcheck_error_strings[]; ...@@ -171,8 +169,8 @@ extern char *aclcheck_error_strings[];
/* /*
* routines used internally (parser, etc.) * routines used internally (parser, etc.)
*/ */
extern Acl *aclownerdefault(char *relname, AclId ownerid); extern Acl *acldefault(char *relname, AclId ownerid);
extern Acl *acldefault(char *relname);
extern Acl *aclinsert3(Acl *old_acl, AclItem *mod_aip, unsigned modechg); extern Acl *aclinsert3(Acl *old_acl, AclItem *mod_aip, unsigned modechg);
extern char *aclmakepriv(char *old_privlist, char new_priv); extern char *aclmakepriv(char *old_privlist, char new_priv);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment