8
8
*
9
9
*
10
10
* IDENTIFICATION
11
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.99 2003/09/25 06:58:03 petere Exp $
11
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.100 2003/10/29 22:20:54 tgl Exp $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
@@ -542,26 +542,23 @@ acldefault(GrantObjectType objtype, AclId ownerid)
542
542
break ;
543
543
}
544
544
545
- acl = allocacl ((world_default != ACL_NO_RIGHTS ? 1 : 0 )
546
- + (ownerid ? 1 : 0 ));
545
+ acl = allocacl ((world_default != ACL_NO_RIGHTS ) ? 2 : 1 );
547
546
aip = ACL_DAT (acl );
548
547
549
548
if (world_default != ACL_NO_RIGHTS )
550
549
{
551
- aip [0 ].ai_grantee = ACL_ID_WORLD ;
552
- aip [0 ].ai_grantor = ownerid ;
553
- ACLITEM_SET_PRIVS_IDTYPE (aip [0 ], world_default , ACL_NO_RIGHTS , ACL_IDTYPE_WORLD );
550
+ aip -> ai_grantee = ACL_ID_WORLD ;
551
+ aip -> ai_grantor = ownerid ;
552
+ ACLITEM_SET_PRIVS_IDTYPE (* aip , world_default , ACL_NO_RIGHTS ,
553
+ ACL_IDTYPE_WORLD );
554
+ aip ++ ;
554
555
}
555
556
556
- if (ownerid )
557
- {
558
- int index = (world_default != ACL_NO_RIGHTS ? 1 : 0 );
559
-
560
- aip [index ].ai_grantee = ownerid ;
561
- aip [index ].ai_grantor = ownerid ;
562
- /* owner gets default privileges with grant option */
563
- ACLITEM_SET_PRIVS_IDTYPE (aip [index ], owner_default , owner_default , ACL_IDTYPE_UID );
564
- }
557
+ aip -> ai_grantee = ownerid ;
558
+ aip -> ai_grantor = ownerid ;
559
+ /* owner gets default privileges with grant option */
560
+ ACLITEM_SET_PRIVS_IDTYPE (* aip , owner_default , owner_default ,
561
+ ACL_IDTYPE_UID );
565
562
566
563
return acl ;
567
564
}
@@ -574,17 +571,22 @@ acldefault(GrantObjectType objtype, AclId ownerid)
574
571
* NB: caller is responsible for having detoasted the input ACL, if needed.
575
572
*/
576
573
Acl *
577
- aclinsert3 (const Acl * old_acl , const AclItem * mod_aip , unsigned modechg , DropBehavior behavior )
574
+ aclinsert3 (const Acl * old_acl , const AclItem * mod_aip ,
575
+ unsigned modechg , DropBehavior behavior )
578
576
{
579
577
Acl * new_acl = NULL ;
580
578
AclItem * old_aip ,
581
579
* new_aip = NULL ;
580
+ AclMode old_privs ,
581
+ old_goptions ,
582
+ new_privs ,
583
+ new_goptions ;
582
584
int dst ,
583
585
num ;
584
586
585
587
/* These checks for null input are probably dead code, but... */
586
- if (!old_acl || ACL_NUM (old_acl ) < 1 )
587
- old_acl = allocacl (1 );
588
+ if (!old_acl || ACL_NUM (old_acl ) < 0 )
589
+ old_acl = allocacl (0 );
588
590
if (!mod_aip )
589
591
{
590
592
new_acl = allocacl (ACL_NUM (old_acl ));
@@ -629,16 +631,23 @@ aclinsert3(const Acl *old_acl, const AclItem *mod_aip, unsigned modechg, DropBeh
629
631
num ++ ; /* set num to the size of new_acl */
630
632
}
631
633
632
- /* apply the permissions mod */
634
+ old_privs = ACLITEM_GET_PRIVS (new_aip [dst ]);
635
+ old_goptions = ACLITEM_GET_GOPTIONS (new_aip [dst ]);
636
+
637
+ /* apply the specified permissions change */
633
638
switch (modechg )
634
639
{
635
640
case ACL_MODECHG_ADD :
636
- ACLITEM_SET_PRIVS (new_aip [dst ], ACLITEM_GET_PRIVS (new_aip [dst ]) | ACLITEM_GET_PRIVS (* mod_aip ));
637
- ACLITEM_SET_GOPTIONS (new_aip [dst ], ACLITEM_GET_GOPTIONS (new_aip [dst ]) | ACLITEM_GET_GOPTIONS (* mod_aip ));
641
+ ACLITEM_SET_PRIVS (new_aip [dst ],
642
+ old_privs | ACLITEM_GET_PRIVS (* mod_aip ));
643
+ ACLITEM_SET_GOPTIONS (new_aip [dst ],
644
+ old_goptions | ACLITEM_GET_GOPTIONS (* mod_aip ));
638
645
break ;
639
646
case ACL_MODECHG_DEL :
640
- ACLITEM_SET_PRIVS (new_aip [dst ], ACLITEM_GET_PRIVS (new_aip [dst ]) & ~ACLITEM_GET_PRIVS (* mod_aip ));
641
- ACLITEM_SET_GOPTIONS (new_aip [dst ], ACLITEM_GET_GOPTIONS (new_aip [dst ]) & ~ACLITEM_GET_GOPTIONS (* mod_aip ));
647
+ ACLITEM_SET_PRIVS (new_aip [dst ],
648
+ old_privs & ~ACLITEM_GET_PRIVS (* mod_aip ));
649
+ ACLITEM_SET_GOPTIONS (new_aip [dst ],
650
+ old_goptions & ~ACLITEM_GET_GOPTIONS (* mod_aip ));
642
651
break ;
643
652
case ACL_MODECHG_EQL :
644
653
ACLITEM_SET_PRIVS_IDTYPE (new_aip [dst ],
@@ -648,10 +657,13 @@ aclinsert3(const Acl *old_acl, const AclItem *mod_aip, unsigned modechg, DropBeh
648
657
break ;
649
658
}
650
659
660
+ new_privs = ACLITEM_GET_PRIVS (new_aip [dst ]);
661
+ new_goptions = ACLITEM_GET_GOPTIONS (new_aip [dst ]);
662
+
651
663
/*
652
664
* If the adjusted entry has no permissions, delete it from the list.
653
665
*/
654
- if (ACLITEM_GET_PRIVS ( new_aip [ dst ]) == ACL_NO_RIGHTS )
666
+ if (new_privs == ACL_NO_RIGHTS && new_goptions == ACL_NO_RIGHTS )
655
667
{
656
668
memmove (new_aip + dst ,
657
669
new_aip + dst + 1 ,
@@ -661,12 +673,14 @@ aclinsert3(const Acl *old_acl, const AclItem *mod_aip, unsigned modechg, DropBeh
661
673
}
662
674
663
675
/*
664
- * Remove abandoned privileges (cascading revoke)
676
+ * Remove abandoned privileges (cascading revoke). Currently we
677
+ * can only handle this when the grantee is a user.
665
678
*/
666
- if (modechg != ACL_MODECHG_ADD
667
- && ACLITEM_GET_IDTYPE (* mod_aip ) == ACL_IDTYPE_UID
668
- && ACLITEM_GET_GOPTIONS (* mod_aip ))
669
- new_acl = recursive_revoke (new_acl , mod_aip -> ai_grantee , ACLITEM_GET_GOPTIONS (* mod_aip ), behavior );
679
+ if ((old_goptions & ~new_goptions ) != 0
680
+ && ACLITEM_GET_IDTYPE (* mod_aip ) == ACL_IDTYPE_UID )
681
+ new_acl = recursive_revoke (new_acl , mod_aip -> ai_grantee ,
682
+ (old_goptions & ~new_goptions ),
683
+ behavior );
670
684
671
685
return new_acl ;
672
686
}
@@ -744,8 +758,8 @@ aclremove(PG_FUNCTION_ARGS)
744
758
new_num ;
745
759
746
760
/* These checks for null input should be dead code, but... */
747
- if (!old_acl || ACL_NUM (old_acl ) < 1 )
748
- old_acl = allocacl (1 );
761
+ if (!old_acl || ACL_NUM (old_acl ) < 0 )
762
+ old_acl = allocacl (0 );
749
763
if (!mod_aip )
750
764
{
751
765
new_acl = allocacl (ACL_NUM (old_acl ));
@@ -773,27 +787,14 @@ aclremove(PG_FUNCTION_ARGS)
773
787
new_num = old_num - 1 ;
774
788
new_acl = allocacl (new_num );
775
789
new_aip = ACL_DAT (new_acl );
776
- if (dst == 0 )
777
- { /* start */
778
- ereport (ERROR ,
779
- (errcode (ERRCODE_DATA_EXCEPTION ),
780
- errmsg ("aclitem for public may not be removed" )));
781
- }
782
- else if (dst == old_num - 1 )
783
- { /* end */
784
- memcpy ((char * ) new_aip ,
785
- (char * ) old_aip ,
786
- new_num * sizeof (AclItem ));
787
- }
788
- else
789
- { /* middle */
790
+ if (dst > 0 )
790
791
memcpy ((char * ) new_aip ,
791
792
(char * ) old_aip ,
792
793
dst * sizeof (AclItem ));
794
+ if (dst < new_num )
793
795
memcpy ((char * ) (new_aip + dst ),
794
796
(char * ) (old_aip + dst + 1 ),
795
797
(new_num - dst ) * sizeof (AclItem ));
796
- }
797
798
}
798
799
799
800
PG_RETURN_ACL_P (new_acl );
@@ -839,7 +840,7 @@ makeaclitem(PG_FUNCTION_ARGS)
839
840
840
841
if (u_grantee == 0 && g_grantee == 0 )
841
842
{
842
- aclitem -> ai_grantee = 0 ;
843
+ aclitem -> ai_grantee = ACL_ID_WORLD ;
843
844
844
845
ACLITEM_SET_IDTYPE (* aclitem , ACL_IDTYPE_WORLD );
845
846
}
@@ -851,18 +852,18 @@ makeaclitem(PG_FUNCTION_ARGS)
851
852
}
852
853
else if (u_grantee != 0 )
853
854
{
854
- aclitem -> ai_grantee = u_grantee ;
855
+ aclitem -> ai_grantee = u_grantee ;
855
856
856
857
ACLITEM_SET_IDTYPE (* aclitem , ACL_IDTYPE_UID );
857
858
}
858
- else if (g_grantee != 0 )
859
+ else /* (g_grantee != 0) */
859
860
{
860
- aclitem -> ai_grantee = g_grantee ;
861
+ aclitem -> ai_grantee = g_grantee ;
861
862
862
863
ACLITEM_SET_IDTYPE (* aclitem , ACL_IDTYPE_GID );
863
864
}
864
865
865
- aclitem -> ai_grantor = grantor ;
866
+ aclitem -> ai_grantor = grantor ;
866
867
867
868
ACLITEM_SET_PRIVS (* aclitem , priv );
868
869
if (goption )
0 commit comments