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.
This commit is contained in:
parent
46cf925728
commit
7215f74b89
@ -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 @@
|
|||||||
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[] = {
|
|||||||
"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)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
* ChangeAcl
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
ChangeAcl(char *relname,
|
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,
|
|||||||
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);
|
ownerId = ((Form_pg_class) GETSTRUCT(tuple))->relowner;
|
||||||
free_old_acl = true;
|
old_acl = acldefault(relname, ownerId);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
/* Need to detoast the old ACL for modification */
|
|
||||||
old_acl = DatumGetAclP(PointerGetDatum(old_acl));
|
|
||||||
|
|
||||||
if (ACL_NUM(old_acl) < 1)
|
|
||||||
{
|
{
|
||||||
#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,
|
|||||||
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)
|
|||||||
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)
|
|||||||
*/
|
*/
|
||||||
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)
|
|||||||
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)
|
|||||||
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 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* 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)
|
|||||||
(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)
|
|||||||
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 @@
|
|||||||
* 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 @@
|
|||||||
*/
|
*/
|
||||||
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;
|
|||||||
#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;
|
|||||||
#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[];
|
|||||||
/*
|
/*
|
||||||
* 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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user