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.
3636static int32 aclcheck (char * relname ,Acl * acl ,AclId id ,
3737AclIdType 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 codesabove . */
40+ /*MUST correspond to the order of the ACLCHK_* result codesin acl.h . */
6141char * 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
6950static
7051dumpacl (Acl * acl )
@@ -84,7 +65,7 @@ dumpacl(Acl *acl)
8465#endif
8566
8667/*
87- *
68+ * ChangeAcl
8869 */
8970void
9071ChangeAcl (char * relname ,
@@ -96,12 +77,12 @@ ChangeAcl(char *relname,
9677* new_acl ;
9778Relation relation ;
9879HeapTuple tuple ;
80+ Datum aclDatum ;
9981Datum values [Natts_pg_class ];
10082char nulls [Natts_pg_class ];
10183char replaces [Natts_pg_class ];
10284Relation idescs [Num_pg_class_indices ];
10385bool 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,
11899relname );
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 );
125104if (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,
173145CatalogCloseIndices (Num_pg_class_indices ,idescs );
174146
175147heap_close (relation ,RowExclusiveLock );
176- if ( free_old_acl )
177- pfree (old_acl );
148+
149+ pfree (old_acl );
178150pfree (new_acl );
179151}
180152
@@ -264,9 +236,15 @@ aclcheck(char *relname, Acl *acl, AclId id, AclIdType idtype, AclMode mode)
264236unsigned num ,
265237found_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+ */
268243if (!acl )
269- acl = acldefault (relname );
244+ {
245+ elog (DEBUG ,"aclcheck: null ACL, returning 1" );
246+ return ACLCHECK_OK ;
247+ }
270248
271249num = ACL_NUM (acl );
272250aidat = ACL_DAT (acl );
@@ -278,9 +256,7 @@ aclcheck(char *relname, Acl *acl, AclId id, AclIdType idtype, AclMode mode)
278256 */
279257if (num < 1 )
280258{
281- #if defined(ACLDEBUG_TRACE )|| 1
282259elog (DEBUG ,"aclcheck: zero-length ACL, returning 1" );
283- #endif
284260return ACLCHECK_OK ;
285261}
286262
@@ -357,11 +333,12 @@ aclcheck(char *relname, Acl *acl, AclId id, AclIdType idtype, AclMode mode)
357333int32
358334pg_aclcheck (char * relname ,Oid userid ,AclMode mode )
359335{
360- HeapTuple tuple ;
361- Acl * acl = (Acl * )NULL ;
362336int32 result ;
337+ HeapTuple tuple ;
363338char * usename ;
364- Relation relation ;
339+ Datum aclDatum ;
340+ bool isNull ;
341+ Acl * acl ;
365342
366343tuple = SearchSysCacheTuple (SHADOWSYSID ,
367344ObjectIdGetDatum (userid ),
@@ -399,53 +376,31 @@ pg_aclcheck(char *relname, Oid userid, AclMode mode)
399376return 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+ */
404382tuple = SearchSysCacheTuple (RELNAME ,
405383PointerGetDatum (relname ),
4063840 ,0 ,0 );
407385if (!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 */
427393AclId ownerId ;
428394
429395ownerId = ((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+
449404result = aclcheck (relname ,acl ,userid , (AclIdType )ACL_IDTYPE_UID ,mode );
450405if (acl )
451406pfree (acl );