Skip to content

Commit 7d0c418

Browse files
committed
Make acl-related functions safe for TOAST. Mark pg_class.relacl as
compressible but not externally storable (since we're not sure about whether creating a toast relation for pg_class would work).
1 parent b7319d3 commit 7d0c418

File tree

7 files changed

+195
-176
lines changed

7 files changed

+195
-176
lines changed

src/backend/access/heap/tuptoaster.c

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/access/heap/tuptoaster.c,v 1.9 2000/07/22 11:18:46 wieck Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/access/heap/tuptoaster.c,v 1.10 2000/07/31 22:39:17 tgl Exp $
1212
*
1313
*
1414
* INTERFACE ROUTINES
@@ -273,7 +273,7 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
273273

274274
/* ----------
275275
* If the old value is an external stored one, check if it
276-
* has changed so we have to detele it later.
276+
* has changed so we have to delete it later.
277277
* ----------
278278
*/
279279
if (!old_isnull && att[i]->attlen == -1 &&
@@ -336,17 +336,16 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
336336
if (att[i]->attlen == -1)
337337
{
338338
/* ----------
339-
* If the tables attribute say's PLAIN allways, we
340-
* do so below.
339+
* If the table's attribute says PLAIN always, force it so.
341340
* ----------
342341
*/
343342
if (att[i]->attstorage == 'p')
344343
toast_action[i] = 'p';
345344

346345
/* ----------
347-
* We're running for UPDATE, so any TOASTed value we find
348-
* still in the tuple must be someone elses we cannot reuse.
349-
* Expand it to plain and eventually toast it again below.
346+
* We took care of UPDATE above, so any TOASTed value we find
347+
* still in the tuple must be someone else's we cannot reuse.
348+
* Expand it to plain (and, probably, toast it again below).
350349
* ----------
351350
*/
352351
if (VARATT_IS_EXTENDED(DatumGetPointer(toast_values[i])))
@@ -367,7 +366,7 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
367366
else
368367
{
369368
/* ----------
370-
* Not a variable size attribute, plain storage allways
369+
* Not a variable size attribute, plain storage always
371370
* ----------
372371
*/
373372
toast_action[i] = 'p';

src/backend/catalog/aclchk.c

Lines changed: 53 additions & 44 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.38 2000/04/12 17:14:55 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.39 2000/07/31 22:39:13 tgl Exp $
1212
*
1313
* NOTES
1414
* See acl.h.
@@ -33,7 +33,8 @@
3333
#include "utils/acl.h"
3434
#include "utils/syscache.h"
3535

36-
static int32 aclcheck(char *relname, Acl *acl, AclId id, AclIdType idtype, AclMode mode);
36+
static int32 aclcheck(char *relname, Acl *acl, AclId id,
37+
AclIdType idtype, AclMode mode);
3738

3839
/*
3940
* Enable use of user relations in place of real system catalogs.
@@ -68,14 +69,16 @@ char *aclcheck_error_strings[] = {
6869
static
6970
dumpacl(Acl *acl)
7071
{
71-
unsigned i;
72+
int i;
7273
AclItem *aip;
7374

7475
elog(DEBUG, "acl size = %d, # acls = %d",
7576
ACL_SIZE(acl), ACL_NUM(acl));
76-
aip = (AclItem *) ACL_DAT(acl);
77+
aip = ACL_DAT(acl);
7778
for (i = 0; i < ACL_NUM(acl); ++i)
78-
elog(DEBUG, " acl[%d]: %s", i, aclitemout(aip + i));
79+
elog(DEBUG, " acl[%d]: %s", i,
80+
DatumGetCString(DirectFunctionCall1(aclitemout,
81+
PointerGetDatum(aip + i))));
7982
}
8083

8184
#endif
@@ -89,22 +92,20 @@ ChangeAcl(char *relname,
8992
unsigned modechg)
9093
{
9194
unsigned i;
92-
Acl *old_acl = (Acl *) NULL,
95+
Acl *old_acl,
9396
*new_acl;
9497
Relation relation;
9598
HeapTuple tuple;
9699
Datum values[Natts_pg_class];
97100
char nulls[Natts_pg_class];
98101
char replaces[Natts_pg_class];
99102
Relation idescs[Num_pg_class_indices];
100-
int free_old_acl = 0;
103+
bool isNull;
104+
bool free_old_acl = false;
101105

102106
/*
103107
* Find the pg_class tuple matching 'relname' and extract the ACL. If
104108
* there's no ACL, create a default using the pg_class.relowner field.
105-
*
106-
* We can't use the syscache here, since we need to do a heap_update on
107-
* the tuple we find.
108109
*/
109110
relation = heap_openr(RelationRelationName, RowExclusiveLock);
110111
tuple = SearchSysCacheTuple(RELNAME,
@@ -117,25 +118,37 @@ ChangeAcl(char *relname,
117118
relname);
118119
}
119120

120-
if (!heap_attisnull(tuple, Anum_pg_class_relacl))
121-
old_acl = (Acl *) heap_getattr(tuple,
122-
Anum_pg_class_relacl,
123-
RelationGetDescr(relation),
124-
(bool *) NULL);
125-
if (!old_acl || ACL_NUM(old_acl) < 1)
121+
old_acl = (Acl *) heap_getattr(tuple,
122+
Anum_pg_class_relacl,
123+
RelationGetDescr(relation),
124+
&isNull);
125+
if (isNull)
126126
{
127127
#ifdef ACLDEBUG_TRACE
128128
elog(DEBUG, "ChangeAcl: using default ACL");
129129
#endif
130-
/* old_acl = acldefault(((Form_pg_class) GETSTRUCT(tuple))->relowner); */
131130
old_acl = acldefault(relname);
132-
free_old_acl = 1;
131+
free_old_acl = true;
132+
}
133+
134+
/* Need to detoast the old ACL for modification */
135+
old_acl = DatumGetAclP(PointerGetDatum(old_acl));
136+
137+
if (ACL_NUM(old_acl) < 1)
138+
{
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;
133144
}
134145

135146
#ifdef ACLDEBUG_TRACE
136147
dumpacl(old_acl);
137148
#endif
149+
138150
new_acl = aclinsert3(old_acl, mod_aip, modechg);
151+
139152
#ifdef ACLDEBUG_TRACE
140153
dumpacl(new_acl);
141154
#endif
@@ -148,7 +161,7 @@ ChangeAcl(char *relname,
148161
* anyway */
149162
}
150163
replaces[Anum_pg_class_relacl - 1] = 'r';
151-
values[Anum_pg_class_relacl - 1] = (Datum) new_acl;
164+
values[Anum_pg_class_relacl - 1] = PointerGetDatum(new_acl);
152165
tuple = heap_modifytuple(tuple, relation, values, nulls, replaces);
153166

154167
heap_update(relation, &tuple->t_self, tuple, NULL);
@@ -193,20 +206,20 @@ get_groname(AclId grosysid)
193206
if (HeapTupleIsValid(tuple))
194207
name = NameStr(((Form_pg_group) GETSTRUCT(tuple))->groname);
195208
else
196-
elog(NOTICE, "get_groname: group %d not found", grosysid);
209+
elog(NOTICE, "get_groname: group %u not found", grosysid);
197210
return name;
198211
}
199212

200-
static int32
213+
static bool
201214
in_group(AclId uid, AclId gid)
202215
{
203216
Relation relation;
204217
HeapTuple tuple;
205218
Acl *tmp;
206-
unsigned i,
219+
int i,
207220
num;
208221
AclId *aidp;
209-
int32 found = 0;
222+
bool found = false;
210223

211224
relation = heap_openr(GroupRelationName, RowExclusiveLock);
212225
tuple = SearchSysCacheTuple(GROSYSID,
@@ -219,13 +232,15 @@ in_group(AclId uid, AclId gid)
219232
Anum_pg_group_grolist,
220233
RelationGetDescr(relation),
221234
(bool *) NULL);
235+
/* be sure the IdList is not toasted */
236+
tmp = DatumGetIdListP(PointerGetDatum(tmp));
222237
/* XXX make me a function */
223238
num = IDLIST_NUM(tmp);
224239
aidp = IDLIST_DAT(tmp);
225240
for (i = 0; i < num; ++i)
226241
if (aidp[i] == uid)
227242
{
228-
found = 1;
243+
found = true;
229244
break;
230245
}
231246
}
@@ -344,8 +359,7 @@ pg_aclcheck(char *relname, char *usename, AclMode mode)
344359
{
345360
HeapTuple tuple;
346361
AclId id;
347-
Acl *acl = (Acl *) NULL,
348-
*tmp;
362+
Acl *acl = (Acl *) NULL;
349363
int32 result;
350364
Relation relation;
351365

@@ -396,12 +410,11 @@ pg_aclcheck(char *relname, char *usename, AclMode mode)
396410
}
397411
if (!heap_attisnull(tuple, Anum_pg_class_relacl))
398412
{
399-
tmp = (Acl *) heap_getattr(tuple,
400-
Anum_pg_class_relacl,
401-
RelationGetDescr(relation),
402-
(bool *) NULL);
403-
acl = makeacl(ACL_NUM(tmp));
404-
memmove((char *) acl, (char *) tmp, ACL_SIZE(tmp));
413+
/* get a detoasted copy of the ACL */
414+
acl = DatumGetAclPCopy(heap_getattr(tuple,
415+
Anum_pg_class_relacl,
416+
RelationGetDescr(relation),
417+
(bool *) NULL));
405418
}
406419
else
407420
{
@@ -410,13 +423,10 @@ pg_aclcheck(char *relname, char *usename, AclMode mode)
410423
* if the acl is null, by default the owner can do whatever he
411424
* wants to with it
412425
*/
413-
int4 ownerId;
426+
AclId ownerId;
414427

415-
ownerId = (int4) heap_getattr(tuple,
416-
Anum_pg_class_relowner,
417-
RelationGetDescr(relation),
418-
(bool *) NULL);
419-
acl = aclownerdefault(relname, (AclId) ownerId);
428+
ownerId = ((Form_pg_class) GETSTRUCT(tuple))->relowner;
429+
acl = aclownerdefault(relname, ownerId);
420430
}
421431
heap_close(relation, RowExclusiveLock);
422432
#else
@@ -427,12 +437,11 @@ pg_aclcheck(char *relname, char *usename, AclMode mode)
427437
if (HeapTupleIsValid(tuple) &&
428438
!heap_attisnull(tuple, Anum_pg_class_relacl))
429439
{
430-
tmp = (Acl *) heap_getattr(tuple,
431-
Anum_pg_class_relacl,
432-
RelationGetDescr(relation),
433-
(bool *) NULL);
434-
acl = makeacl(ACL_NUM(tmp));
435-
memmove((char *) acl, (char *) tmp, ACL_SIZE(tmp));
440+
/* get a detoasted copy of the ACL */
441+
acl = DatumGetAclPCopy(heap_getattr(tuple,
442+
Anum_pg_class_relacl,
443+
RelationGetDescr(relation),
444+
(bool *) NULL));
436445
}
437446
heap_close(relation, RowExclusiveLock);
438447
#endif

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy