Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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

+7-8
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

+53-44
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)