Skip to content

Commit 7215f74

Browse files
committed
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.
1 parent 46cf925 commit 7215f74

File tree

3 files changed

+68
-117
lines changed

3 files changed

+68
-117
lines changed

src/backend/catalog/aclchk.c

Lines changed: 43 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.40 2000/09/06 14:15:15 petere Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.41 2000/10/02 04:49:28 tgl Exp $
1212
*
1313
* NOTES
1414
* See acl.h.
@@ -36,35 +36,16 @@
3636
static int32 aclcheck(char *relname, Acl *acl, AclId id,
3737
AclIdType idtype, AclMode mode);
3838

39-
/*
40-
* Enable use of user relations in place of real system catalogs.
41-
*/
42-
/*#define ACLDEBUG*/
43-
44-
#ifdef ACLDEBUG
45-
/*
46-
* Fool the code below into thinking that "pgacls" is pg_class.
47-
* relname and relowner are in the same place, happily.
48-
*/
49-
#undef Anum_pg_class_relacl
50-
#define Anum_pg_class_relacl 3
51-
#undef Natts_pg_class
52-
#define Natts_pg_class 3
53-
#undef Name_pg_class
54-
#define Name_pg_class "pgacls"
55-
#undef Name_pg_group
56-
#define Name_pg_group "pggroup"
57-
#endif
58-
5939
/* warning messages, now more explicit. */
60-
/* should correspond to the order of the ACLCHK_* result codes above. */
40+
/* MUST correspond to the order of the ACLCHK_* result codes in acl.h. */
6141
char *aclcheck_error_strings[] = {
6242
"No error.",
6343
"Permission denied.",
6444
"Table does not exist.",
6545
"Must be table owner."
6646
};
6747

48+
6849
#ifdef ACLDEBUG_TRACE
6950
static
7051
dumpacl(Acl *acl)
@@ -84,7 +65,7 @@ dumpacl(Acl *acl)
8465
#endif
8566

8667
/*
87-
*
68+
* ChangeAcl
8869
*/
8970
void
9071
ChangeAcl(char *relname,
@@ -96,12 +77,12 @@ ChangeAcl(char *relname,
9677
*new_acl;
9778
Relation relation;
9879
HeapTuple tuple;
80+
Datum aclDatum;
9981
Datum values[Natts_pg_class];
10082
char nulls[Natts_pg_class];
10183
char replaces[Natts_pg_class];
10284
Relation idescs[Num_pg_class_indices];
10385
bool isNull;
104-
bool free_old_acl = false;
10586

10687
/*
10788
* Find the pg_class tuple matching 'relname' and extract the ACL. If
@@ -118,29 +99,20 @@ ChangeAcl(char *relname,
11899
relname);
119100
}
120101

121-
old_acl = (Acl *) heap_getattr(tuple,
122-
Anum_pg_class_relacl,
123-
RelationGetDescr(relation),
124-
&isNull);
102+
aclDatum = SysCacheGetAttr(RELNAME, tuple, Anum_pg_class_relacl,
103+
&isNull);
125104
if (isNull)
126105
{
127-
#ifdef ACLDEBUG_TRACE
128-
elog(DEBUG, "ChangeAcl: using default ACL");
129-
#endif
130-
old_acl = acldefault(relname);
131-
free_old_acl = true;
132-
}
133-
134-
/* Need to detoast the old ACL for modification */
135-
old_acl = DatumGetAclP(PointerGetDatum(old_acl));
106+
/* No ACL, so build default ACL for rel */
107+
AclId ownerId;
136108

137-
if (ACL_NUM(old_acl) < 1)
109+
ownerId = ((Form_pg_class) GETSTRUCT(tuple))->relowner;
110+
old_acl = acldefault(relname, ownerId);
111+
}
112+
else
138113
{
139-
#ifdef ACLDEBUG_TRACE
140-
elog(DEBUG, "ChangeAcl: old ACL has zero length");
141-
#endif
142-
old_acl = acldefault(relname);
143-
free_old_acl = true;
114+
/* get a detoasted copy of the rel's ACL */
115+
old_acl = DatumGetAclPCopy(aclDatum);
144116
}
145117

146118
#ifdef ACLDEBUG_TRACE
@@ -173,8 +145,8 @@ ChangeAcl(char *relname,
173145
CatalogCloseIndices(Num_pg_class_indices, idescs);
174146

175147
heap_close(relation, RowExclusiveLock);
176-
if (free_old_acl)
177-
pfree(old_acl);
148+
149+
pfree(old_acl);
178150
pfree(new_acl);
179151
}
180152

@@ -264,9 +236,15 @@ aclcheck(char *relname, Acl *acl, AclId id, AclIdType idtype, AclMode mode)
264236
unsigned num,
265237
found_group;
266238

267-
/* if no acl is found, use world default */
239+
/*
240+
* If ACL is null, default to "OK" --- this should not happen,
241+
* since caller should have inserted appropriate default
242+
*/
268243
if (!acl)
269-
acl = acldefault(relname);
244+
{
245+
elog(DEBUG, "aclcheck: null ACL, returning 1");
246+
return ACLCHECK_OK;
247+
}
270248

271249
num = ACL_NUM(acl);
272250
aidat = ACL_DAT(acl);
@@ -278,9 +256,7 @@ aclcheck(char *relname, Acl *acl, AclId id, AclIdType idtype, AclMode mode)
278256
*/
279257
if (num < 1)
280258
{
281-
#if defined(ACLDEBUG_TRACE) || 1
282259
elog(DEBUG, "aclcheck: zero-length ACL, returning 1");
283-
#endif
284260
return ACLCHECK_OK;
285261
}
286262

@@ -357,11 +333,12 @@ aclcheck(char *relname, Acl *acl, AclId id, AclIdType idtype, AclMode mode)
357333
int32
358334
pg_aclcheck(char *relname, Oid userid, AclMode mode)
359335
{
360-
HeapTuple tuple;
361-
Acl *acl = (Acl *) NULL;
362336
int32 result;
337+
HeapTuple tuple;
363338
char *usename;
364-
Relation relation;
339+
Datum aclDatum;
340+
bool isNull;
341+
Acl *acl;
365342

366343
tuple = SearchSysCacheTuple(SHADOWSYSID,
367344
ObjectIdGetDatum(userid),
@@ -399,53 +376,31 @@ pg_aclcheck(char *relname, Oid userid, AclMode mode)
399376
return ACLCHECK_OK;
400377
}
401378

402-
#ifndef ACLDEBUG
403-
relation = heap_openr(RelationRelationName, RowExclusiveLock);
379+
/*
380+
* Normal case: get the relation's ACL from pg_class
381+
*/
404382
tuple = SearchSysCacheTuple(RELNAME,
405383
PointerGetDatum(relname),
406384
0, 0, 0);
407385
if (!HeapTupleIsValid(tuple))
408-
{
409-
elog(ERROR, "pg_aclcheck: class \"%s\" not found",
410-
relname);
411-
}
412-
if (!heap_attisnull(tuple, Anum_pg_class_relacl))
413-
{
414-
/* get a detoasted copy of the ACL */
415-
acl = DatumGetAclPCopy(heap_getattr(tuple,
416-
Anum_pg_class_relacl,
417-
RelationGetDescr(relation),
418-
(bool *) NULL));
419-
}
420-
else
421-
{
386+
elog(ERROR, "pg_aclcheck: class \"%s\" not found", relname);
422387

423-
/*
424-
* if the acl is null, by default the owner can do whatever he
425-
* wants to with it
426-
*/
388+
aclDatum = SysCacheGetAttr(RELNAME, tuple, Anum_pg_class_relacl,
389+
&isNull);
390+
if (isNull)
391+
{
392+
/* No ACL, so build default ACL for rel */
427393
AclId ownerId;
428394

429395
ownerId = ((Form_pg_class) GETSTRUCT(tuple))->relowner;
430-
acl = aclownerdefault(relname, ownerId);
396+
acl = acldefault(relname, ownerId);
431397
}
432-
heap_close(relation, RowExclusiveLock);
433-
#else
434-
relation = heap_openr(RelationRelationName, RowExclusiveLock);
435-
tuple = SearchSysCacheTuple(RELNAME,
436-
PointerGetDatum(relname),
437-
0, 0, 0);
438-
if (HeapTupleIsValid(tuple) &&
439-
!heap_attisnull(tuple, Anum_pg_class_relacl))
398+
else
440399
{
441-
/* get a detoasted copy of the ACL */
442-
acl = DatumGetAclPCopy(heap_getattr(tuple,
443-
Anum_pg_class_relacl,
444-
RelationGetDescr(relation),
445-
(bool *) NULL));
400+
/* get a detoasted copy of the rel's ACL */
401+
acl = DatumGetAclPCopy(aclDatum);
446402
}
447-
heap_close(relation, RowExclusiveLock);
448-
#endif
403+
449404
result = aclcheck(relname, acl, userid, (AclIdType) ACL_IDTYPE_UID, mode);
450405
if (acl)
451406
pfree(acl);

src/backend/utils/adt/acl.c

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.48 2000/07/31 22:39:09 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.49 2000/10/02 04:49:27 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -334,12 +334,23 @@ aclitemgt(AclItem *a1, AclItem *a2)
334334
(a1->ai_idtype == a2->ai_idtype && a1->ai_id > a2->ai_id));
335335
}
336336

337+
338+
/*
339+
* acldefault() --- create an ACL describing default access permissions
340+
*
341+
* Change this routine if you want to alter the default access policy for
342+
* newly-created tables (or any table with a NULL acl entry in pg_class)
343+
*/
337344
Acl *
338-
aclownerdefault(char *relname, AclId ownerid)
345+
acldefault(char *relname, AclId ownerid)
339346
{
340347
Acl *acl;
341348
AclItem *aip;
342349

350+
#define ACL_WORLD_DEFAULT (ACL_NO)
351+
/* #define ACL_WORLD_DEFAULT (ACL_RD|ACL_WR|ACL_AP|ACL_RU) */
352+
#define ACL_OWNER_DEFAULT (ACL_RD|ACL_WR|ACL_AP|ACL_RU)
353+
343354
acl = makeacl(2);
344355
aip = ACL_DAT(acl);
345356
aip[0].ai_idtype = ACL_IDTYPE_WORLD;
@@ -351,19 +362,6 @@ aclownerdefault(char *relname, AclId ownerid)
351362
return acl;
352363
}
353364

354-
Acl *
355-
acldefault(char *relname)
356-
{
357-
Acl *acl;
358-
AclItem *aip;
359-
360-
acl = makeacl(1);
361-
aip = ACL_DAT(acl);
362-
aip[0].ai_idtype = ACL_IDTYPE_WORLD;
363-
aip[0].ai_id = ACL_ID_WORLD;
364-
aip[0].ai_mode = IsSystemRelationName(relname) ? ACL_RD : ACL_WORLD_DEFAULT;
365-
return acl;
366-
}
367365

368366
/*
369367
* Add or replace an item in an ACL array.

src/include/utils/acl.h

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@
77
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $Id: acl.h,v 1.27 2000/09/06 14:15:31 petere Exp $
10+
* $Id: acl.h,v 1.28 2000/10/02 04:49:27 tgl Exp $
1111
*
1212
* NOTES
1313
* For backward-compatibility purposes we have to allow there
1414
* to be a null ACL in a pg_class tuple. This will be defined as
15-
* meaning "no protection" (i.e., old catalogs get old semantics).
15+
* meaning "default protection" (i.e., whatever acldefault() returns).
1616
*
1717
* The AclItems in an ACL array are currently kept in sorted order.
1818
* Things will break hard if you change that without changing the
@@ -32,7 +32,7 @@
3232
*/
3333
typedef uint32 AclId;
3434

35-
#define ACL_ID_WORLD 0 /* XXX only idtype should be checked */
35+
#define ACL_ID_WORLD 0 /* placeholder for id in a WORLD acl item */
3636

3737
/*
3838
* AclIdType tag that describes if the AclId is a user, group, etc.
@@ -58,15 +58,6 @@ typedef uint8 AclMode;
5858
#define ACL_RU (1<<3) /* place rules */
5959
#define N_ACL_MODES 4
6060

61-
#define ACL_MODECHG_ADD 1
62-
#define ACL_MODECHG_DEL 2
63-
#define ACL_MODECHG_EQL 3
64-
65-
/* change this line if you want to set the default acl permission */
66-
#define ACL_WORLD_DEFAULT (ACL_NO)
67-
/* #define ACL_WORLD_DEFAULT (ACL_RD|ACL_WR|ACL_AP|ACL_RU) */
68-
#define ACL_OWNER_DEFAULT (ACL_RD|ACL_WR|ACL_AP|ACL_RU)
69-
7061
/*
7162
* AclItem
7263
*/
@@ -143,6 +134,13 @@ typedef ArrayType IdList;
143134
#define PG_RETURN_IDLIST_P(x) PG_RETURN_POINTER(x)
144135

145136

137+
/*
138+
* ACL modification opcodes
139+
*/
140+
#define ACL_MODECHG_ADD 1
141+
#define ACL_MODECHG_DEL 2
142+
#define ACL_MODECHG_EQL 3
143+
146144
/* mode indicators for I/O */
147145
#define ACL_MODECHG_STR "+-=" /* list of valid characters */
148146
#define ACL_MODECHG_ADD_CHR '+'
@@ -171,8 +169,8 @@ extern char *aclcheck_error_strings[];
171169
/*
172170
* routines used internally (parser, etc.)
173171
*/
174-
extern Acl *aclownerdefault(char *relname, AclId ownerid);
175-
extern Acl *acldefault(char *relname);
172+
extern Acl *acldefault(char *relname, AclId ownerid);
173+
176174
extern Acl *aclinsert3(Acl *old_acl, AclItem *mod_aip, unsigned modechg);
177175

178176
extern char *aclmakepriv(char *old_privlist, char new_priv);

0 commit comments

Comments
 (0)