88 *
99 *
1010 * IDENTIFICATION
11- * $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.51 2000/10/16 17:08:08 momjian Exp $
11+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.52 2000/11/03 19:01:36 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -212,8 +212,7 @@ makeacl(int n)
212212if (n < 0 )
213213elog (ERROR ,"makeacl: invalid size: %d" ,n );
214214size = ACL_N_SIZE (n );
215- if (!(new_acl = (Acl * )palloc (size )))
216- elog (ERROR ,"makeacl: palloc failed on %d" ,size );
215+ new_acl = (Acl * )palloc (size );
217216MemSet ((char * )new_acl ,0 ,size );
218217new_acl -> size = size ;
219218new_acl -> ndim = 1 ;
@@ -382,7 +381,7 @@ aclinsert3(Acl *old_acl, AclItem *mod_aip, unsigned modechg)
382381
383382/* These checks for null input are probably dead code, but... */
384383if (!old_acl || ACL_NUM (old_acl )< 1 )
385- old_acl = makeacl (0 );
384+ old_acl = makeacl (1 );
386385if (!mod_aip )
387386{
388387new_acl = makeacl (ACL_NUM (old_acl ));
@@ -402,12 +401,13 @@ aclinsert3(Acl *old_acl, AclItem *mod_aip, unsigned modechg)
402401/* find the first element not less than the element to be inserted */
403402for (dst = 0 ;dst < num && aclitemgt (mod_aip ,old_aip + dst );++ dst )
404403;
404+
405405if (dst < num && aclitemeq (mod_aip ,old_aip + dst ))
406406{
407407/* modify in-place */
408- new_acl = makeacl (ACL_NUM (old_acl ));
409- memcpy ((char * )new_acl , (char * )old_acl ,ACL_SIZE (old_acl ));
408+ new_acl = makeacl (num );
410409new_aip = ACL_DAT (new_acl );
410+ memcpy ((char * )new_acl , (char * )old_acl ,ACL_SIZE (old_acl ));
411411src = dst ;
412412}
413413else
@@ -420,24 +420,26 @@ aclinsert3(Acl *old_acl, AclItem *mod_aip, unsigned modechg)
420420}
421421else if (dst >=num )
422422{/* end */
423- memmove ((char * )new_aip ,
424- (char * )old_aip ,
425- num * sizeof (AclItem ));
423+ memcpy ((char * )new_aip ,
424+ (char * )old_aip ,
425+ num * sizeof (AclItem ));
426426}
427427else
428428{/* middle */
429- memmove ((char * )new_aip ,
430- (char * )old_aip ,
431- dst * sizeof (AclItem ));
432- memmove ((char * ) (new_aip + dst + 1 ),
433- (char * ) (old_aip + dst ),
434- (num - dst )* sizeof (AclItem ));
429+ memcpy ((char * )new_aip ,
430+ (char * )old_aip ,
431+ dst * sizeof (AclItem ));
432+ memcpy ((char * ) (new_aip + dst + 1 ),
433+ (char * ) (old_aip + dst ),
434+ (num - dst )* sizeof (AclItem ));
435435}
436436new_aip [dst ].ai_id = mod_aip -> ai_id ;
437437new_aip [dst ].ai_idtype = mod_aip -> ai_idtype ;
438438num ++ ;/* set num to the size of new_acl */
439- src = 0 ;/* world entry */
439+ src = 0 ;/*if add or del, start from world entry */
440440}
441+
442+ /* apply the permissions mod */
441443switch (modechg )
442444{
443445case ACL_MODECHG_ADD :
@@ -452,11 +454,11 @@ aclinsert3(Acl *old_acl, AclItem *mod_aip, unsigned modechg)
452454}
453455
454456/*
455- * if thenewly added entry has no permissions, delete it from the
457+ * if theadjusted entry has no permissions, delete it from the
456458 * list. For example, this helps in removing entries for users who no
457- * longer exist.. .
459+ * longer exist. EXCEPTION: never remove the world entry .
458460 */
459- if (new_aip [dst ].ai_mode == 0 )
461+ if (new_aip [dst ].ai_mode == 0 && dst > 0 )
460462{
461463int i ;
462464
@@ -467,7 +469,7 @@ aclinsert3(Acl *old_acl, AclItem *mod_aip, unsigned modechg)
467469new_aip [i - 1 ].ai_mode = new_aip [i ].ai_mode ;
468470}
469471ARR_DIMS (new_acl )[0 ]= num - 1 ;
470- /* Adjust also the array size because it is used formemmove */
472+ /* Adjust also the array size because it is used formemcpy */
471473ARR_SIZE (new_acl )-= sizeof (AclItem );
472474}
473475
@@ -500,7 +502,7 @@ aclremove(PG_FUNCTION_ARGS)
500502
501503/* These checks for null input should be dead code, but... */
502504if (!old_acl || ACL_NUM (old_acl )< 1 )
503- old_acl = makeacl (0 );
505+ old_acl = makeacl (1 );
504506if (!mod_aip )
505507{
506508new_acl = makeacl (ACL_NUM (old_acl ));
@@ -511,11 +513,14 @@ aclremove(PG_FUNCTION_ARGS)
511513old_num = ACL_NUM (old_acl );
512514old_aip = ACL_DAT (old_acl );
513515
516+ /* Search for the matching entry */
514517for (dst = 0 ;dst < old_num && !aclitemeq (mod_aip ,old_aip + dst );++ dst )
515518;
519+
516520if (dst >=old_num )
517- {/* not found or empty */
518- new_acl = makeacl (ACL_NUM (old_acl ));
521+ {
522+ /* Not found, so return copy of source ACL */
523+ new_acl = makeacl (old_num );
519524memcpy ((char * )new_acl , (char * )old_acl ,ACL_SIZE (old_acl ));
520525}
521526else
@@ -529,20 +534,21 @@ aclremove(PG_FUNCTION_ARGS)
529534}
530535else if (dst == old_num - 1 )
531536{/* end */
532- memmove ((char * )new_aip ,
533- (char * )old_aip ,
534- new_num * sizeof (AclItem ));
537+ memcpy ((char * )new_aip ,
538+ (char * )old_aip ,
539+ new_num * sizeof (AclItem ));
535540}
536541else
537542{/* middle */
538- memmove ((char * )new_aip ,
539- (char * )old_aip ,
540- dst * sizeof (AclItem ));
541- memmove ((char * ) (new_aip + dst ),
542- (char * ) (old_aip + dst + 1 ),
543- (new_num - dst )* sizeof (AclItem ));
543+ memcpy ((char * )new_aip ,
544+ (char * )old_aip ,
545+ dst * sizeof (AclItem ));
546+ memcpy ((char * ) (new_aip + dst ),
547+ (char * ) (old_aip + dst + 1 ),
548+ (new_num - dst )* sizeof (AclItem ));
544549}
545550}
551+
546552PG_RETURN_ACL_P (new_acl );
547553}
548554