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)
212212 if (n < 0 )
213213 elog (ERROR , "makeacl: invalid size: %d" , n );
214214 size = 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 );
217216 MemSet ((char * ) new_acl , 0 , size );
218217 new_acl -> size = size ;
219218 new_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... */
384383 if (!old_acl || ACL_NUM (old_acl ) < 1 )
385- old_acl = makeacl (0 );
384+ old_acl = makeacl (1 );
386385 if (!mod_aip )
387386 {
388387 new_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 */
403402 for (dst = 0 ; dst < num && aclitemgt (mod_aip , old_aip + dst ); ++ dst )
404403 ;
404+
405405 if (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 );
410409 new_aip = ACL_DAT (new_acl );
410+ memcpy ((char * ) new_acl , (char * ) old_acl , ACL_SIZE (old_acl ));
411411 src = dst ;
412412 }
413413 else
@@ -420,24 +420,26 @@ aclinsert3(Acl *old_acl, AclItem *mod_aip, unsigned modechg)
420420 }
421421 else 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 }
427427 else
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 }
436436 new_aip [dst ].ai_id = mod_aip -> ai_id ;
437437 new_aip [dst ].ai_idtype = mod_aip -> ai_idtype ;
438438 num ++ ; /* 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 */
441443 switch (modechg )
442444 {
443445 case ACL_MODECHG_ADD :
@@ -452,11 +454,11 @@ aclinsert3(Acl *old_acl, AclItem *mod_aip, unsigned modechg)
452454 }
453455
454456 /*
455- * if the newly added entry has no permissions, delete it from the
457+ * if the adjusted 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 {
461463 int i ;
462464
@@ -467,7 +469,7 @@ aclinsert3(Acl *old_acl, AclItem *mod_aip, unsigned modechg)
467469 new_aip [i - 1 ].ai_mode = new_aip [i ].ai_mode ;
468470 }
469471 ARR_DIMS (new_acl )[0 ] = num - 1 ;
470- /* Adjust also the array size because it is used for memmove */
472+ /* Adjust also the array size because it is used for memcpy */
471473 ARR_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... */
502504 if (!old_acl || ACL_NUM (old_acl ) < 1 )
503- old_acl = makeacl (0 );
505+ old_acl = makeacl (1 );
504506 if (!mod_aip )
505507 {
506508 new_acl = makeacl (ACL_NUM (old_acl ));
@@ -511,11 +513,14 @@ aclremove(PG_FUNCTION_ARGS)
511513 old_num = ACL_NUM (old_acl );
512514 old_aip = ACL_DAT (old_acl );
513515
516+ /* Search for the matching entry */
514517 for (dst = 0 ; dst < old_num && !aclitemeq (mod_aip , old_aip + dst ); ++ dst )
515518 ;
519+
516520 if (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 );
519524 memcpy ((char * ) new_acl , (char * ) old_acl , ACL_SIZE (old_acl ));
520525 }
521526 else
@@ -529,20 +534,21 @@ aclremove(PG_FUNCTION_ARGS)
529534 }
530535 else 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 }
536541 else
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+
546552 PG_RETURN_ACL_P (new_acl );
547553}
548554
0 commit comments