8
8
*
9
9
*
10
10
* IDENTIFICATION
11
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.87 2003/06/02 19:00:29 tgl Exp $
11
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/acl.c,v 1.88 2003/06/11 09:23:55 petere Exp $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
32
32
33
33
static const char * getid (const char * s ,char * n );
34
34
static void putid (char * p ,const char * s );
35
- static Acl * makeacl (int n );
35
+ static Acl * allocacl (int n );
36
36
static const char * aclparse (const char * s ,AclItem * aip );
37
37
static bool aclitemeq (const AclItem * a1 ,const AclItem * a2 );
38
38
static Acl * recursive_revoke (Acl * acl ,AclId grantee ,
39
39
AclMode revoke_privs ,DropBehavior behavior );
40
40
41
+ static AclMode convert_priv_string (text * priv_type_text );
42
+
41
43
static Oid convert_table_name (text * tablename );
42
44
static AclMode convert_table_priv_string (text * priv_type_text );
43
45
static Oid convert_database_name (text * databasename );
@@ -265,20 +267,20 @@ aclparse(const char *s, AclItem *aip)
265
267
}
266
268
267
269
/*
268
- *makeacl
270
+ *allocacl
269
271
*Allocates storage for a new Acl with 'n' entries.
270
272
*
271
273
* RETURNS:
272
274
*the new Acl
273
275
*/
274
276
static Acl *
275
- makeacl (int n )
277
+ allocacl (int n )
276
278
{
277
279
Acl * new_acl ;
278
280
Size size ;
279
281
280
282
if (n < 0 )
281
- elog (ERROR ,"makeacl : invalid size: %d" ,n );
283
+ elog (ERROR ,"allocacl : invalid size: %d" ,n );
282
284
size = ACL_N_SIZE (n );
283
285
new_acl = (Acl * )palloc0 (size );
284
286
new_acl -> size = size ;
@@ -471,7 +473,7 @@ acldefault(GrantObjectType objtype, AclId ownerid)
471
473
break ;
472
474
}
473
475
474
- acl = makeacl ((world_default != ACL_NO_RIGHTS ?1 :0 )
476
+ acl = allocacl ((world_default != ACL_NO_RIGHTS ?1 :0 )
475
477
+ (ownerid ?1 :0 ));
476
478
aip = ACL_DAT (acl );
477
479
@@ -513,10 +515,10 @@ aclinsert3(const Acl *old_acl, const AclItem *mod_aip, unsigned modechg, DropBeh
513
515
514
516
/* These checks for null input are probably dead code, but... */
515
517
if (!old_acl || ACL_NUM (old_acl )< 1 )
516
- old_acl = makeacl (1 );
518
+ old_acl = allocacl (1 );
517
519
if (!mod_aip )
518
520
{
519
- new_acl = makeacl (ACL_NUM (old_acl ));
521
+ new_acl = allocacl (ACL_NUM (old_acl ));
520
522
memcpy ((char * )new_acl , (char * )old_acl ,ACL_SIZE (old_acl ));
521
523
return new_acl ;
522
524
}
@@ -536,7 +538,7 @@ aclinsert3(const Acl *old_acl, const AclItem *mod_aip, unsigned modechg, DropBeh
536
538
if (aclitemeq (mod_aip ,old_aip + dst ))
537
539
{
538
540
/* found a match, so modify existing item */
539
- new_acl = makeacl (num );
541
+ new_acl = allocacl (num );
540
542
new_aip = ACL_DAT (new_acl );
541
543
memcpy (new_acl ,old_acl ,ACL_SIZE (old_acl ));
542
544
break ;
@@ -546,7 +548,7 @@ aclinsert3(const Acl *old_acl, const AclItem *mod_aip, unsigned modechg, DropBeh
546
548
if (dst == num )
547
549
{
548
550
/* need to append a new item */
549
- new_acl = makeacl (num + 1 );
551
+ new_acl = allocacl (num + 1 );
550
552
new_aip = ACL_DAT (new_acl );
551
553
memcpy (new_aip ,old_aip ,num * sizeof (AclItem ));
552
554
@@ -671,10 +673,10 @@ aclremove(PG_FUNCTION_ARGS)
671
673
672
674
/* These checks for null input should be dead code, but... */
673
675
if (!old_acl || ACL_NUM (old_acl )< 1 )
674
- old_acl = makeacl (1 );
676
+ old_acl = allocacl (1 );
675
677
if (!mod_aip )
676
678
{
677
- new_acl = makeacl (ACL_NUM (old_acl ));
679
+ new_acl = allocacl (ACL_NUM (old_acl ));
678
680
memcpy ((char * )new_acl , (char * )old_acl ,ACL_SIZE (old_acl ));
679
681
PG_RETURN_ACL_P (new_acl );
680
682
}
@@ -689,13 +691,13 @@ aclremove(PG_FUNCTION_ARGS)
689
691
if (dst >=old_num )
690
692
{
691
693
/* Not found, so return copy of source ACL */
692
- new_acl = makeacl (old_num );
694
+ new_acl = allocacl (old_num );
693
695
memcpy ((char * )new_acl , (char * )old_acl ,ACL_SIZE (old_acl ));
694
696
}
695
697
else
696
698
{
697
699
new_num = old_num - 1 ;
698
- new_acl = makeacl (new_num );
700
+ new_acl = allocacl (new_num );
699
701
new_aip = ACL_DAT (new_acl );
700
702
if (dst == 0 )
701
703
{/* start */
@@ -734,13 +736,97 @@ aclcontains(PG_FUNCTION_ARGS)
734
736
aidat = ACL_DAT (acl );
735
737
for (i = 0 ;i < num ;++ i )
736
738
{
737
- if (aip -> ai_grantee == aidat [i ].ai_grantee &&
738
- aip -> ai_privs == aidat [i ].ai_privs )
739
+ if (aip -> ai_grantee == aidat [i ].ai_grantee
740
+ && ACLITEM_GET_IDTYPE (* aip )== ACLITEM_GET_IDTYPE (aidat [i ])
741
+ && aip -> ai_grantor == aidat [i ].ai_grantor
742
+ && (ACLITEM_GET_PRIVS (* aip )& ACLITEM_GET_PRIVS (aidat [i ]))== ACLITEM_GET_PRIVS (* aip )
743
+ && (ACLITEM_GET_GOPTIONS (* aip )& ACLITEM_GET_GOPTIONS (aidat [i ]))== ACLITEM_GET_GOPTIONS (* aip ))
739
744
PG_RETURN_BOOL (true);
740
745
}
741
746
PG_RETURN_BOOL (false);
742
747
}
743
748
749
+ Datum
750
+ makeaclitem (PG_FUNCTION_ARGS )
751
+ {
752
+ int32 u_grantee = PG_GETARG_INT32 (0 );
753
+ int32 g_grantee = PG_GETARG_INT32 (1 );
754
+ int32 grantor = PG_GETARG_INT32 (2 );
755
+ text * privtext = PG_GETARG_TEXT_P (3 );
756
+ bool goption = PG_GETARG_BOOL (4 );
757
+ AclItem * aclitem ;
758
+ AclMode priv ;
759
+
760
+ priv = convert_priv_string (privtext );
761
+
762
+ aclitem = (AclItem * )palloc (sizeof (* aclitem ));
763
+ if (u_grantee == 0 && g_grantee == 0 )
764
+ {
765
+ aclitem -> ai_grantee = 0 ;
766
+ ACLITEM_SET_IDTYPE (* aclitem ,ACL_IDTYPE_WORLD );
767
+ }
768
+ else if (u_grantee != 0 && g_grantee != 0 )
769
+ {
770
+ elog (ERROR ,"cannot specify both user and group" );
771
+ }
772
+ else if (u_grantee != 0 )
773
+ {
774
+ aclitem -> ai_grantee = u_grantee ;
775
+ ACLITEM_SET_IDTYPE (* aclitem ,ACL_IDTYPE_UID );
776
+ }
777
+ else if (g_grantee != 0 )
778
+ {
779
+ aclitem -> ai_grantee = g_grantee ;
780
+ ACLITEM_SET_IDTYPE (* aclitem ,ACL_IDTYPE_GID );
781
+ }
782
+
783
+ aclitem -> ai_grantor = grantor ;
784
+ ACLITEM_SET_PRIVS (* aclitem ,priv );
785
+ if (goption )
786
+ ACLITEM_SET_GOPTIONS (* aclitem ,priv );
787
+ else
788
+ ACLITEM_SET_GOPTIONS (* aclitem ,ACL_NO_RIGHTS );
789
+
790
+ PG_RETURN_ACLITEM_P (aclitem );
791
+ }
792
+
793
+ static AclMode
794
+ convert_priv_string (text * priv_type_text )
795
+ {
796
+ char * priv_type ;
797
+
798
+ priv_type = DatumGetCString (DirectFunctionCall1 (textout ,
799
+ PointerGetDatum (priv_type_text )));
800
+
801
+ if (strcasecmp (priv_type ,"SELECT" )== 0 )
802
+ return ACL_SELECT ;
803
+ if (strcasecmp (priv_type ,"INSERT" )== 0 )
804
+ return ACL_INSERT ;
805
+ if (strcasecmp (priv_type ,"UPDATE" )== 0 )
806
+ return ACL_UPDATE ;
807
+ if (strcasecmp (priv_type ,"DELETE" )== 0 )
808
+ return ACL_DELETE ;
809
+ if (strcasecmp (priv_type ,"RULE" )== 0 )
810
+ return ACL_RULE ;
811
+ if (strcasecmp (priv_type ,"REFERENCES" )== 0 )
812
+ return ACL_REFERENCES ;
813
+ if (strcasecmp (priv_type ,"TRIGGER" )== 0 )
814
+ return ACL_TRIGGER ;
815
+ if (strcasecmp (priv_type ,"EXECUTE" )== 0 )
816
+ return ACL_EXECUTE ;
817
+ if (strcasecmp (priv_type ,"USAGE" )== 0 )
818
+ return ACL_USAGE ;
819
+ if (strcasecmp (priv_type ,"CREATE" )== 0 )
820
+ return ACL_CREATE ;
821
+ if (strcasecmp (priv_type ,"TEMP" )== 0 )
822
+ return ACL_CREATE_TEMP ;
823
+ if (strcasecmp (priv_type ,"TEMPORARY" )== 0 )
824
+ return ACL_CREATE_TEMP ;
825
+
826
+ elog (ERROR ,"invalid privilege type %s" ,priv_type );
827
+ return ACL_NO_RIGHTS ;/* keep compiler quiet */
828
+ }
829
+
744
830
745
831
/*
746
832
* has_table_privilege variants