8
8
*
9
9
*
10
10
* IDENTIFICATION
11
- * $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.41 2000/10/02 04:49:28 tgl Exp $
11
+ * $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.42 2000/11/03 19:02:18 tgl Exp $
12
12
*
13
13
* NOTES
14
14
* See acl.h.
@@ -185,41 +185,40 @@ get_groname(AclId grosysid)
185
185
static bool
186
186
in_group (AclId uid , AclId gid )
187
187
{
188
- Relation relation ;
189
188
HeapTuple tuple ;
190
- Acl * tmp ;
189
+ Datum att ;
190
+ bool isNull ;
191
+ IdList * tmp ;
192
+ AclId * aidp ;
191
193
int i ,
192
194
num ;
193
- AclId * aidp ;
194
- bool found = false;
195
195
196
- relation = heap_openr (GroupRelationName , RowExclusiveLock );
197
196
tuple = SearchSysCacheTuple (GROSYSID ,
198
197
ObjectIdGetDatum (gid ),
199
198
0 , 0 , 0 );
200
- if (HeapTupleIsValid (tuple ) &&
201
- !heap_attisnull (tuple , Anum_pg_group_grolist ))
199
+ if (HeapTupleIsValid (tuple ))
202
200
{
203
- tmp = (IdList * ) heap_getattr (tuple ,
204
- Anum_pg_group_grolist ,
205
- RelationGetDescr (relation ),
206
- (bool * ) NULL );
207
- /* be sure the IdList is not toasted */
208
- tmp = DatumGetIdListP (PointerGetDatum (tmp ));
209
- /* XXX make me a function */
210
- num = IDLIST_NUM (tmp );
211
- aidp = IDLIST_DAT (tmp );
212
- for (i = 0 ; i < num ; ++ i )
213
- if (aidp [i ] == uid )
201
+ att = SysCacheGetAttr (GROSYSID ,
202
+ tuple ,
203
+ Anum_pg_group_grolist ,
204
+ & isNull );
205
+ if (!isNull )
206
+ {
207
+ /* be sure the IdList is not toasted */
208
+ tmp = DatumGetIdListP (att );
209
+ /* scan it */
210
+ num = IDLIST_NUM (tmp );
211
+ aidp = IDLIST_DAT (tmp );
212
+ for (i = 0 ; i < num ; ++ i )
214
213
{
215
- found = true;
216
- break ;
214
+ if ( aidp [ i ] == uid )
215
+ return true ;
217
216
}
217
+ }
218
218
}
219
219
else
220
- elog (NOTICE , "in_group: group %d not found" , gid );
221
- heap_close (relation , RowExclusiveLock );
222
- return found ;
220
+ elog (NOTICE , "in_group: group %u not found" , gid );
221
+ return false;
223
222
}
224
223
225
224
/*
@@ -230,11 +229,10 @@ in_group(AclId uid, AclId gid)
230
229
static int32
231
230
aclcheck (char * relname , Acl * acl , AclId id , AclIdType idtype , AclMode mode )
232
231
{
233
- unsigned i ;
234
232
AclItem * aip ,
235
233
* aidat ;
236
- unsigned num ,
237
- found_group ;
234
+ int i ,
235
+ num ;
238
236
239
237
/*
240
238
* If ACL is null, default to "OK" --- this should not happen,
@@ -252,52 +250,54 @@ aclcheck(char *relname, Acl *acl, AclId id, AclIdType idtype, AclMode mode)
252
250
/*
253
251
* We'll treat the empty ACL like that, too, although this is more
254
252
* like an error (i.e., you manually blew away your ACL array) -- the
255
- * system never creates an empty ACL.
253
+ * system never creates an empty ACL, since there must always be
254
+ * a "world" entry in the first slot.
256
255
*/
257
256
if (num < 1 )
258
257
{
259
258
elog (DEBUG , "aclcheck: zero-length ACL, returning 1" );
260
259
return ACLCHECK_OK ;
261
260
}
261
+ Assert (aidat -> ai_idtype == ACL_IDTYPE_WORLD );
262
262
263
263
switch (idtype )
264
264
{
265
265
case ACL_IDTYPE_UID :
266
+ /* Look for exact match to user */
266
267
for (i = 1 , aip = aidat + 1 ; /* skip world entry */
267
268
i < num && aip -> ai_idtype == ACL_IDTYPE_UID ;
268
269
++ i , ++ aip )
269
270
{
270
271
if (aip -> ai_id == id )
271
272
{
272
273
#ifdef ACLDEBUG_TRACE
273
- elog (DEBUG , "aclcheck: found %d /%d" ,
274
+ elog (DEBUG , "aclcheck: found user %u /%d" ,
274
275
aip -> ai_id , aip -> ai_mode );
275
276
#endif
276
277
return (aip -> ai_mode & mode ) ? ACLCHECK_OK : ACLCHECK_NO_PRIV ;
277
278
}
278
279
}
279
- for (found_group = 0 ;
280
+ /* See if he has the permission via any group */
281
+ for (;
280
282
i < num && aip -> ai_idtype == ACL_IDTYPE_GID ;
281
283
++ i , ++ aip )
282
284
{
283
- if (in_group ( id , aip -> ai_id ) )
285
+ if (aip -> ai_mode & mode )
284
286
{
285
- if (aip -> ai_mode & mode )
287
+ if (in_group ( id , aip -> ai_id ) )
286
288
{
287
- found_group = 1 ;
288
- break ;
289
- }
290
- }
291
- }
292
- if (found_group )
293
- {
294
289
#ifdef ACLDEBUG_TRACE
295
- elog (DEBUG , "aclcheck: all groups ok" );
290
+ elog (DEBUG , "aclcheck: found group %u/%d" ,
291
+ aip -> ai_id , aip -> ai_mode );
296
292
#endif
297
- return ACLCHECK_OK ;
293
+ return ACLCHECK_OK ;
294
+ }
295
+ }
298
296
}
297
+ /* Else, look to the world entry */
299
298
break ;
300
299
case ACL_IDTYPE_GID :
300
+ /* Look for this group ID */
301
301
for (i = 1 , aip = aidat + 1 ; /* skip world entry and
302
302
* UIDs */
303
303
i < num && aip -> ai_idtype == ACL_IDTYPE_UID ;
@@ -310,14 +310,16 @@ aclcheck(char *relname, Acl *acl, AclId id, AclIdType idtype, AclMode mode)
310
310
if (aip -> ai_id == id )
311
311
{
312
312
#ifdef ACLDEBUG_TRACE
313
- elog (DEBUG , "aclcheck: found %d /%d" ,
313
+ elog (DEBUG , "aclcheck: found group %u /%d" ,
314
314
aip -> ai_id , aip -> ai_mode );
315
315
#endif
316
316
return (aip -> ai_mode & mode ) ? ACLCHECK_OK : ACLCHECK_NO_PRIV ;
317
317
}
318
318
}
319
+ /* Else, look to the world entry */
319
320
break ;
320
321
case ACL_IDTYPE_WORLD :
322
+ /* Only check the world entry */
321
323
break ;
322
324
default :
323
325
elog (ERROR , "aclcheck: bogus ACL id type: %d" , idtype );
0 commit comments