22
22
#include "catalog/indexing.h"
23
23
#include "catalog/namespace.h"
24
24
#include "catalog/objectaccess.h"
25
+ #include "catalog/pg_authid.h"
25
26
#include "catalog/pg_policy.h"
26
27
#include "catalog/pg_type.h"
27
28
#include "commands/policy.h"
48
49
static void RangeVarCallbackForPolicy (const RangeVar * rv ,
49
50
Oid relid , Oid oldrelid , void * arg );
50
51
static char parse_policy_command (const char * cmd_name );
51
- static ArrayType * policy_role_list_to_array (List * roles );
52
+ static Datum * policy_role_list_to_array (List * roles , int * num_roles );
52
53
53
54
/*
54
55
* Callback to RangeVarGetRelidExtended().
@@ -130,30 +131,28 @@ parse_policy_command(const char *cmd_name)
130
131
131
132
/*
132
133
* policy_role_list_to_array
133
- * helper function to convert a list of RoleSpecs to an array of role ids.
134
+ * helper function to convert a list of RoleSpecs to an array of
135
+ * role id Datums.
134
136
*/
135
- static ArrayType *
136
- policy_role_list_to_array (List * roles )
137
+ static Datum *
138
+ policy_role_list_to_array (List * roles , int * num_roles )
137
139
{
138
- ArrayType * role_ids ;
139
- Datum * temp_array ;
140
+ Datum * role_oids ;
140
141
ListCell * cell ;
141
- int num_roles ;
142
142
int i = 0 ;
143
143
144
144
/* Handle no roles being passed in as being for public */
145
145
if (roles == NIL )
146
146
{
147
- temp_array = (Datum * ) palloc (sizeof (Datum ));
148
- temp_array [0 ] = ObjectIdGetDatum (ACL_ID_PUBLIC );
147
+ * num_roles = 1 ;
148
+ role_oids = (Datum * ) palloc (* num_roles * sizeof (Datum ));
149
+ role_oids [0 ] = ObjectIdGetDatum (ACL_ID_PUBLIC );
149
150
150
- role_ids = construct_array (temp_array , 1 , OIDOID , sizeof (Oid ), true,
151
- 'i' );
152
- return role_ids ;
151
+ return role_oids ;
153
152
}
154
153
155
- num_roles = list_length (roles );
156
- temp_array = (Datum * ) palloc (num_roles * sizeof (Datum ));
154
+ * num_roles = list_length (roles );
155
+ role_oids = (Datum * ) palloc (* num_roles * sizeof (Datum ));
157
156
158
157
foreach (cell , roles )
159
158
{
@@ -164,24 +163,24 @@ policy_role_list_to_array(List *roles)
164
163
*/
165
164
if (spec -> roletype == ROLESPEC_PUBLIC )
166
165
{
167
- if (num_roles != 1 )
166
+ if (* num_roles != 1 )
167
+ {
168
168
ereport (WARNING ,
169
169
(errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
170
170
errmsg ("ignoring roles specified other than public" ),
171
171
errhint ("All roles are members of the public role." )));
172
- temp_array [0 ] = ObjectIdGetDatum (ACL_ID_PUBLIC );
173
- num_roles = 1 ;
174
- break ;
172
+ * num_roles = 1 ;
173
+ }
174
+ role_oids [0 ] = ObjectIdGetDatum (ACL_ID_PUBLIC );
175
+
176
+ return role_oids ;
175
177
}
176
178
else
177
- temp_array [i ++ ] =
179
+ role_oids [i ++ ] =
178
180
ObjectIdGetDatum (get_rolespec_oid ((Node * ) spec , false));
179
181
}
180
182
181
- role_ids = construct_array (temp_array , num_roles , OIDOID , sizeof (Oid ), true,
182
- 'i' );
183
-
184
- return role_ids ;
183
+ return role_oids ;
185
184
}
186
185
187
186
/*
@@ -463,6 +462,8 @@ CreatePolicy(CreatePolicyStmt *stmt)
463
462
Relation target_table ;
464
463
Oid table_id ;
465
464
char polcmd ;
465
+ Datum * role_oids ;
466
+ int nitems = 0 ;
466
467
ArrayType * role_ids ;
467
468
ParseState * qual_pstate ;
468
469
ParseState * with_check_pstate ;
@@ -476,6 +477,7 @@ CreatePolicy(CreatePolicyStmt *stmt)
476
477
bool isnull [Natts_pg_policy ];
477
478
ObjectAddress target ;
478
479
ObjectAddress myself ;
480
+ int i ;
479
481
480
482
/* Parse command */
481
483
polcmd = parse_policy_command (stmt -> cmd );
@@ -498,9 +500,10 @@ CreatePolicy(CreatePolicyStmt *stmt)
498
500
(errcode (ERRCODE_SYNTAX_ERROR ),
499
501
errmsg ("only WITH CHECK expression allowed for INSERT" )));
500
502
501
-
502
503
/* Collect role ids */
503
- role_ids = policy_role_list_to_array (stmt -> roles );
504
+ role_oids = policy_role_list_to_array (stmt -> roles , & nitems );
505
+ role_ids = construct_array (role_oids , nitems , OIDOID ,
506
+ sizeof (Oid ), true, 'i' );
504
507
505
508
/* Parse the supplied clause */
506
509
qual_pstate = make_parsestate (NULL );
@@ -614,6 +617,18 @@ CreatePolicy(CreatePolicyStmt *stmt)
614
617
recordDependencyOnExpr (& myself , with_check_qual ,
615
618
with_check_pstate -> p_rtable , DEPENDENCY_NORMAL );
616
619
620
+ /* Register role dependencies */
621
+ target .classId = AuthIdRelationId ;
622
+ target .objectSubId = 0 ;
623
+ for (i = 0 ; i < nitems ; i ++ )
624
+ {
625
+ target .objectId = DatumGetObjectId (role_oids [i ]);
626
+ /* no dependency if public */
627
+ if (target .objectId != ACL_ID_PUBLIC )
628
+ recordSharedDependencyOn (& myself , & target ,
629
+ SHARED_DEPENDENCY_POLICY );
630
+ }
631
+
617
632
/* Invalidate Relation Cache */
618
633
CacheInvalidateRelcache (target_table );
619
634
@@ -641,6 +656,8 @@ AlterPolicy(AlterPolicyStmt *stmt)
641
656
Oid policy_id ;
642
657
Relation target_table ;
643
658
Oid table_id ;
659
+ Datum * role_oids ;
660
+ int nitems = 0 ;
644
661
ArrayType * role_ids = NULL ;
645
662
List * qual_parse_rtable = NIL ;
646
663
List * with_check_parse_rtable = NIL ;
@@ -658,10 +675,15 @@ AlterPolicy(AlterPolicyStmt *stmt)
658
675
Datum cmd_datum ;
659
676
char polcmd ;
660
677
bool polcmd_isnull ;
678
+ int i ;
661
679
662
680
/* Parse role_ids */
663
681
if (stmt -> roles != NULL )
664
- role_ids = policy_role_list_to_array (stmt -> roles );
682
+ {
683
+ role_oids = policy_role_list_to_array (stmt -> roles , & nitems );
684
+ role_ids = construct_array (role_oids , nitems , OIDOID ,
685
+ sizeof (Oid ), true, 'i' );
686
+ }
665
687
666
688
/* Get id of table. Also handles permissions checks. */
667
689
table_id = RangeVarGetRelidExtended (stmt -> table , AccessExclusiveLock ,
@@ -825,6 +847,19 @@ AlterPolicy(AlterPolicyStmt *stmt)
825
847
recordDependencyOnExpr (& myself , with_check_qual , with_check_parse_rtable ,
826
848
DEPENDENCY_NORMAL );
827
849
850
+ /* Register role dependencies */
851
+ deleteSharedDependencyRecordsFor (PolicyRelationId , policy_id , 0 );
852
+ target .classId = AuthIdRelationId ;
853
+ target .objectSubId = 0 ;
854
+ for (i = 0 ; i < nitems ; i ++ )
855
+ {
856
+ target .objectId = DatumGetObjectId (role_oids [i ]);
857
+ /* no dependency if public */
858
+ if (target .objectId != ACL_ID_PUBLIC )
859
+ recordSharedDependencyOn (& myself , & target ,
860
+ SHARED_DEPENDENCY_POLICY );
861
+ }
862
+
828
863
heap_freetuple (new_tuple );
829
864
830
865
/* Invalidate Relation Cache */
0 commit comments