@ -22,7 +22,7 @@
# include "catalog/indexing.h"
# include "catalog/namespace.h"
# include "catalog/objectaccess.h"
# include "catalog/pg_rowsecurit y.h"
# include "catalog/pg_polic y.h"
# include "catalog/pg_type.h"
# include "commands/policy.h"
# include "miscadmin.h"
@ -46,8 +46,8 @@
static void RangeVarCallbackForPolicy ( const RangeVar * rv ,
Oid relid , Oid oldrelid , void * arg ) ;
static char parse_row_securit y_command ( const char * cmd_name ) ;
static ArrayType * rls _role_list_to_array( List * roles ) ;
static char parse_polic y_command ( const char * cmd_name ) ;
static ArrayType * policy _role_list_to_array( List * roles ) ;
/*
* Callback to RangeVarGetRelidExtended ( ) .
@ -95,7 +95,7 @@ RangeVarCallbackForPolicy(const RangeVar *rv, Oid relid, Oid oldrelid,
}
/*
* parse_row_securit y_command -
* parse_polic y_command -
* helper function to convert full command strings to their char
* representation .
*
@ -104,7 +104,7 @@ RangeVarCallbackForPolicy(const RangeVar *rv, Oid relid, Oid oldrelid,
*
*/
static char
parse_row_securit y_command ( const char * cmd_name )
parse_polic y_command ( const char * cmd_name )
{
char cmd ;
@ -128,7 +128,7 @@ parse_row_security_command(const char *cmd_name)
}
/*
* rls _role_list_to_array
* policy _role_list_to_array
* helper function to convert a list of role names in to an array of
* role ids .
*
@ -138,7 +138,7 @@ parse_row_security_command(const char *cmd_name)
* roles - the list of role names to convert .
*/
static ArrayType *
rls _role_list_to_array( List * roles )
policy _role_list_to_array( List * roles )
{
ArrayType * role_ids ;
Datum * temp_array ;
@ -190,7 +190,7 @@ rls_role_list_to_array(List *roles)
}
/*
* Load row - security policy from the catalog , and keep it in
* Load row security policy from the catalog , and keep it in
* the relation cache .
*/
void
@ -204,14 +204,14 @@ RelationBuildRowSecurity(Relation relation)
MemoryContext rscxt = NULL ;
RowSecurityDesc * rsdesc = NULL ;
catalog = heap_open ( RowSecurit yRelationId, AccessShareLock ) ;
catalog = heap_open ( Polic yRelationId, AccessShareLock ) ;
ScanKeyInit ( & skey ,
Anum_pg_rowsecurity_rsec relid ,
Anum_pg_policy_pol relid ,
BTEqualStrategyNumber , F_OIDEQ ,
ObjectIdGetDatum ( RelationGetRelid ( relation ) ) ) ;
sscan = systable_beginscan ( catalog , RowSecurityR elidPolnameIndexId, true ,
sscan = systable_beginscan ( catalog , PolicyPolr elidPolnameIndexId, true ,
NULL , 1 , & skey ) ;
PG_TRY ( ) ;
{
@ -221,7 +221,7 @@ RelationBuildRowSecurity(Relation relation)
* default - deny policy is created .
*/
rscxt = AllocSetContextCreate ( CacheMemoryContext ,
" Row- security descriptor" ,
" row security descriptor" ,
ALLOCSET_SMALL_MINSIZE ,
ALLOCSET_SMALL_INITSIZE ,
ALLOCSET_SMALL_MAXSIZE ) ;
@ -229,7 +229,7 @@ RelationBuildRowSecurity(Relation relation)
rsdesc - > rscxt = rscxt ;
/*
* Loop through the row - level security entr ies for this relation , if
* Loop through the row level security polic ies for this relation , if
* any .
*/
while ( HeapTupleIsValid ( tuple = systable_getnext ( sscan ) ) )
@ -249,7 +249,7 @@ RelationBuildRowSecurity(Relation relation)
oldcxt = MemoryContextSwitchTo ( rscxt ) ;
/* Get policy command */
value_datum = heap_getattr ( tuple , Anum_pg_rowsecurity_rsec cmd ,
value_datum = heap_getattr ( tuple , Anum_pg_policy_pol cmd ,
RelationGetDescr ( catalog ) , & isnull ) ;
if ( isnull )
cmd_value = 0 ;
@ -257,19 +257,19 @@ RelationBuildRowSecurity(Relation relation)
cmd_value = DatumGetChar ( value_datum ) ;
/* Get policy name */
value_datum = heap_getattr ( tuple , Anum_pg_rowsecurity_rsec polname ,
value_datum = heap_getattr ( tuple , Anum_pg_policy_ polname ,
RelationGetDescr ( catalog ) , & isnull ) ;
Assert ( ! isnull ) ;
policy_name_value = DatumGetCString ( value_datum ) ;
/* Get policy roles */
value_datum = heap_getattr ( tuple , Anum_pg_rowsecurity_rsec roles ,
value_datum = heap_getattr ( tuple , Anum_pg_policy_pol roles ,
RelationGetDescr ( catalog ) , & isnull ) ;
Assert ( ! isnull ) ;
roles = DatumGetArrayTypeP ( value_datum ) ;
/* Get policy qual */
value_datum = heap_getattr ( tuple , Anum_pg_rowsecurity_rsec qual ,
value_datum = heap_getattr ( tuple , Anum_pg_policy_pol qual ,
RelationGetDescr ( catalog ) , & isnull ) ;
if ( ! isnull )
{
@ -280,7 +280,7 @@ RelationBuildRowSecurity(Relation relation)
qual_expr = NULL ;
/* Get WITH CHECK qual */
value_datum = heap_getattr ( tuple , Anum_pg_rowsecurity_rsec withcheck ,
value_datum = heap_getattr ( tuple , Anum_pg_policy_pol withcheck ,
RelationGetDescr ( catalog ) , & isnull ) ;
if ( ! isnull )
@ -295,7 +295,7 @@ RelationBuildRowSecurity(Relation relation)
policy = palloc0 ( sizeof ( RowSecurityPolicy ) ) ;
policy - > policy_name = policy_name_value ;
policy - > rsec id = policy_id ;
policy - > policy_ id = policy_id ;
policy - > cmd = cmd_value ;
policy - > roles = roles ;
policy - > qual = copyObject ( qual_expr ) ;
@ -317,7 +317,7 @@ RelationBuildRowSecurity(Relation relation)
/*
* Check if no policies were added
*
* If no policies exist in pg_rowsecurit y for this relation , then we
* If no policies exist in pg_polic y for this relation , then we
* need to create a single default - deny policy . We use InvalidOid for
* the Oid to indicate that this is the default - deny policy ( we may
* decide to ignore the default policy if an extension adds policies ) .
@ -333,7 +333,7 @@ RelationBuildRowSecurity(Relation relation)
policy = palloc0 ( sizeof ( RowSecurityPolicy ) ) ;
policy - > policy_name = pstrdup ( " default-deny policy " ) ;
policy - > rsec id = InvalidOid ;
policy - > policy_ id = InvalidOid ;
policy - > cmd = ' \0 ' ;
policy - > roles = construct_array ( & role , 1 , OIDOID , sizeof ( Oid ) , true ,
' i ' ) ;
@ -364,22 +364,22 @@ RelationBuildRowSecurity(Relation relation)
/*
* RemovePolicyById -
* remove a row - security policy by its OID . If a policy does not exist with
* the provided oid , then an error is raised .
* remove a policy by its OID . If a policy does not exist with the provided
* oid , then an error is raised .
*
* policy_id - the oid of the row - security policy .
* policy_id - the oid of the policy .
*/
void
RemovePolicyById ( Oid policy_id )
{
Relation pg_rowsecurit y_rel ;
Relation pg_polic y_rel ;
SysScanDesc sscan ;
ScanKeyData skey [ 1 ] ;
HeapTuple tuple ;
Oid relid ;
Relation rel ;
pg_rowsecurit y_rel = heap_open ( RowSecurit yRelationId, RowExclusiveLock ) ;
pg_polic y_rel = heap_open ( Polic yRelationId, RowExclusiveLock ) ;
/*
* Find the policy to delete .
@ -389,19 +389,19 @@ RemovePolicyById(Oid policy_id)
BTEqualStrategyNumber , F_OIDEQ ,
ObjectIdGetDatum ( policy_id ) ) ;
sscan = systable_beginscan ( pg_rowsecurity_rel , RowSecurit yOidIndexId , true ,
sscan = systable_beginscan ( pg_policy_rel , Polic yOidIndexId , true ,
NULL , 1 , skey ) ;
tuple = systable_getnext ( sscan ) ;
/* If the policy exists, then remove it, otherwise raise an error. */
if ( ! HeapTupleIsValid ( tuple ) )
elog ( ERROR , " could not find tuple for row-securit y %u " , policy_id ) ;
elog ( ERROR , " could not find tuple for polic y %u " , policy_id ) ;
/*
* Open and exclusive - lock the relation the policy belong to .
*/
relid = ( ( Form_pg_rowsecurit y ) GETSTRUCT ( tuple ) ) - > rsec relid;
relid = ( ( Form_pg_polic y ) GETSTRUCT ( tuple ) ) - > pol relid;
rel = heap_open ( relid , AccessExclusiveLock ) ;
if ( rel - > rd_rel - > relkind ! = RELKIND_RELATION )
@ -416,7 +416,7 @@ RemovePolicyById(Oid policy_id)
errmsg ( " permission denied: \" %s \" is a system catalog " ,
RelationGetRelationName ( rel ) ) ) ) ;
simple_heap_delete ( pg_rowsecurit y_rel , & tuple - > t_self ) ;
simple_heap_delete ( pg_polic y_rel , & tuple - > t_self ) ;
systable_endscan ( sscan ) ;
heap_close ( rel , AccessExclusiveLock ) ;
@ -424,9 +424,8 @@ RemovePolicyById(Oid policy_id)
/*
* Note that , unlike some of the other flags in pg_class , relrowsecurity
* is not just an indication of if policies exist . When relrowsecurity
* is set ( which can be done directly by the user or indirectly by creating
* a policy on the table ) , then all access to the relation must be through
* a policy . If no policy is defined for the relation then a default - deny
* is set by a user , then all access to the relation must be through a
* policy . If no policy is defined for the relation then a default - deny
* policy is created and all records are filtered ( except for queries from
* the owner ) .
*/
@ -434,7 +433,7 @@ RemovePolicyById(Oid policy_id)
CacheInvalidateRelcache ( rel ) ;
/* Clean up */
heap_close ( pg_rowsecurit y_rel , RowExclusiveLock ) ;
heap_close ( pg_polic y_rel , RowExclusiveLock ) ;
}
/*
@ -446,11 +445,11 @@ RemovePolicyById(Oid policy_id)
Oid
CreatePolicy ( CreatePolicyStmt * stmt )
{
Relation pg_rowsecurit y_rel ;
Oid rowsec _id;
Relation pg_polic y_rel ;
Oid policy _id;
Relation target_table ;
Oid table_id ;
char rsec cmd;
char pol cmd;
ArrayType * role_ids ;
ParseState * qual_pstate ;
ParseState * with_check_pstate ;
@ -459,19 +458,19 @@ CreatePolicy(CreatePolicyStmt *stmt)
Node * with_check_qual ;
ScanKeyData skey [ 2 ] ;
SysScanDesc sscan ;
HeapTuple rsec _tuple;
Datum values [ Natts_pg_rowsecurit y ] ;
bool isnull [ Natts_pg_rowsecurit y ] ;
HeapTuple policy _tuple;
Datum values [ Natts_pg_polic y ] ;
bool isnull [ Natts_pg_polic y ] ;
ObjectAddress target ;
ObjectAddress myself ;
/* Parse command */
rseccmd = parse_row_securit y_command( stmt - > cmd ) ;
polcmd = parse_polic y_command( stmt - > cmd ) ;
/*
* If the command is SELECT or DELETE then WITH CHECK should be NULL .
*/
if ( ( rsec cmd = = ACL_SELECT_CHR | | rsec cmd = = ACL_DELETE_CHR )
if ( ( pol cmd = = ACL_SELECT_CHR | | pol cmd = = ACL_DELETE_CHR )
& & stmt - > with_check ! = NULL )
ereport ( ERROR ,
( errcode ( ERRCODE_SYNTAX_ERROR ) ,
@ -481,14 +480,14 @@ CreatePolicy(CreatePolicyStmt *stmt)
* If the command is INSERT then WITH CHECK should be the only expression
* provided .
*/
if ( rsec cmd = = ACL_INSERT_CHR & & stmt - > qual ! = NULL )
if ( pol cmd = = ACL_INSERT_CHR & & stmt - > qual ! = NULL )
ereport ( ERROR ,
( errcode ( ERRCODE_SYNTAX_ERROR ) ,
errmsg ( " only WITH CHECK expression allowed for INSERT " ) ) ) ;
/* Collect role ids */
role_ids = rls _role_list_to_array( stmt - > roles ) ;
role_ids = policy _role_list_to_array( stmt - > roles ) ;
/* Parse the supplied clause */
qual_pstate = make_parsestate ( NULL ) ;
@ -527,74 +526,74 @@ CreatePolicy(CreatePolicyStmt *stmt)
EXPR_KIND_WHERE ,
" POLICY " ) ;
/* Open pg_rowsecurit y catalog */
pg_rowsecurit y_rel = heap_open ( RowSecurit yRelationId, RowExclusiveLock ) ;
/* Open pg_polic y catalog */
pg_polic y_rel = heap_open ( Polic yRelationId, RowExclusiveLock ) ;
/* Set key - row security relation id. */
/* Set key - policy's relation id. */
ScanKeyInit ( & skey [ 0 ] ,
Anum_pg_rowsecurity_rsec relid ,
Anum_pg_policy_pol relid ,
BTEqualStrategyNumber , F_OIDEQ ,
ObjectIdGetDatum ( table_id ) ) ;
/* Set key - row security policy name. */
/* Set key - policy's name. */
ScanKeyInit ( & skey [ 1 ] ,
Anum_pg_rowsecurity_rsec polname ,
Anum_pg_policy_ polname ,
BTEqualStrategyNumber , F_NAMEEQ ,
CStringGetDatum ( stmt - > policy_name ) ) ;
sscan = systable_beginscan ( pg_rowsecurit y_rel ,
RowSecurityR elidPolnameIndexId, true , NULL , 2 ,
sscan = systable_beginscan ( pg_polic y_rel ,
PolicyPolr elidPolnameIndexId, true , NULL , 2 ,
skey ) ;
rsec _tuple = systable_getnext ( sscan ) ;
policy _tuple = systable_getnext ( sscan ) ;
/* Complain if the policy name already exists for the table */
if ( HeapTupleIsValid ( rsec _tuple) )
if ( HeapTupleIsValid ( policy _tuple) )
ereport ( ERROR ,
( errcode ( ERRCODE_DUPLICATE_OBJECT ) ,
errmsg ( " policy \" %s \" for relation \" %s \" already exists " ,
stmt - > policy_name , RelationGetRelationName ( target_table ) ) ) ) ;
values [ Anum_pg_rowsecurity_rsec relid - 1 ] = ObjectIdGetDatum ( table_id ) ;
values [ Anum_pg_rowsecurity_rsec polname - 1 ]
values [ Anum_pg_policy_pol relid - 1 ] = ObjectIdGetDatum ( table_id ) ;
values [ Anum_pg_policy_ polname - 1 ]
= DirectFunctionCall1 ( namein , CStringGetDatum ( stmt - > policy_name ) ) ;
if ( rsec cmd)
values [ Anum_pg_rowsecurity_rsec cmd - 1 ] = CharGetDatum ( rsec cmd) ;
if ( pol cmd)
values [ Anum_pg_policy_pol cmd - 1 ] = CharGetDatum ( pol cmd) ;
else
isnull [ Anum_pg_rowsecurity_rsec cmd - 1 ] = true ;
isnull [ Anum_pg_policy_pol cmd - 1 ] = true ;
values [ Anum_pg_rowsecurity_rsec roles - 1 ] = PointerGetDatum ( role_ids ) ;
values [ Anum_pg_policy_pol roles - 1 ] = PointerGetDatum ( role_ids ) ;
/* Add qual if present. */
if ( qual )
values [ Anum_pg_rowsecurity_rsec qual - 1 ]
values [ Anum_pg_policy_pol qual - 1 ]
= CStringGetTextDatum ( nodeToString ( qual ) ) ;
else
isnull [ Anum_pg_rowsecurity_rsec qual - 1 ] = true ;
isnull [ Anum_pg_policy_pol qual - 1 ] = true ;
/* Add WITH CHECK qual if present */
if ( with_check_qual )
values [ Anum_pg_rowsecurity_rsec withcheck - 1 ]
values [ Anum_pg_policy_pol withcheck - 1 ]
= CStringGetTextDatum ( nodeToString ( with_check_qual ) ) ;
else
isnull [ Anum_pg_rowsecurity_rsec withcheck - 1 ] = true ;
isnull [ Anum_pg_policy_pol withcheck - 1 ] = true ;
rsec _tuple = heap_form_tuple ( RelationGetDescr ( pg_rowsecurit y_rel ) , values ,
isnull ) ;
policy _tuple = heap_form_tuple ( RelationGetDescr ( pg_polic y_rel ) , values ,
isnull ) ;
rowsec _id = simple_heap_insert ( pg_rowsecurity_rel , rsec _tuple ) ;
policy _id = simple_heap_insert ( pg_policy_rel , policy _tuple ) ;
/* Update Indexes */
CatalogUpdateIndexes ( pg_rowsecurity_rel , rsec _tuple ) ;
CatalogUpdateIndexes ( pg_policy_rel , policy _tuple ) ;
/* Record Dependencies */
target . classId = RelationRelationId ;
target . objectId = table_id ;
target . objectSubId = 0 ;
myself . classId = RowSecurit yRelationId;
myself . objectId = rowsec _id;
myself . classId = Polic yRelationId;
myself . objectId = policy _id;
myself . objectSubId = 0 ;
recordDependencyOn ( & myself , & target , DEPENDENCY_AUTO ) ;
@ -609,14 +608,14 @@ CreatePolicy(CreatePolicyStmt *stmt)
CacheInvalidateRelcache ( target_table ) ;
/* Clean up. */
heap_freetuple ( rsec _tuple) ;
heap_freetuple ( policy _tuple) ;
free_parsestate ( qual_pstate ) ;
free_parsestate ( with_check_pstate ) ;
systable_endscan ( sscan ) ;
relation_close ( target_table , NoLock ) ;
heap_close ( pg_rowsecurit y_rel , RowExclusiveLock ) ;
heap_close ( pg_polic y_rel , RowExclusiveLock ) ;
return rowsec _id;
return policy _id;
}
/*
@ -628,8 +627,8 @@ CreatePolicy(CreatePolicyStmt *stmt)
Oid
AlterPolicy ( AlterPolicyStmt * stmt )
{
Relation pg_rowsecurit y_rel ;
Oid rowsec _id;
Relation pg_polic y_rel ;
Oid policy _id;
Relation target_table ;
Oid table_id ;
ArrayType * role_ids = NULL ;
@ -639,20 +638,20 @@ AlterPolicy(AlterPolicyStmt *stmt)
Node * with_check_qual = NULL ;
ScanKeyData skey [ 2 ] ;
SysScanDesc sscan ;
HeapTuple rsec _tuple;
HeapTuple policy _tuple;
HeapTuple new_tuple ;
Datum values [ Natts_pg_rowsecurit y ] ;
bool isnull [ Natts_pg_rowsecurit y ] ;
bool replaces [ Natts_pg_rowsecurit y ] ;
Datum values [ Natts_pg_polic y ] ;
bool isnull [ Natts_pg_polic y ] ;
bool replaces [ Natts_pg_polic y ] ;
ObjectAddress target ;
ObjectAddress myself ;
Datum cmd_datum ;
char rsec cmd;
bool rsec cmd_isnull;
char pol cmd;
bool pol cmd_isnull;
/* Parse role_ids */
if ( stmt - > roles ! = NULL )
role_ids = rls _role_list_to_array( stmt - > roles ) ;
role_ids = policy _role_list_to_array( stmt - > roles ) ;
/* Get id of table. Also handles permissions checks. */
table_id = RangeVarGetRelidExtended ( stmt - > table , AccessExclusiveLock ,
@ -662,7 +661,7 @@ AlterPolicy(AlterPolicyStmt *stmt)
target_table = relation_open ( table_id , NoLock ) ;
/* Parse the row-securit y clause */
/* Parse the using polic y clause */
if ( stmt - > qual )
{
RangeTblEntry * rte ;
@ -675,13 +674,13 @@ AlterPolicy(AlterPolicyStmt *stmt)
qual = transformWhereClause ( qual_pstate , copyObject ( stmt - > qual ) ,
EXPR_KIND_WHERE ,
" ROW SECURIT Y" ) ;
" POLIC Y" ) ;
qual_parse_rtable = qual_pstate - > p_rtable ;
free_parsestate ( qual_pstate ) ;
}
/* Parse the with-check row-securit y clause */
/* Parse the with-check polic y clause */
if ( stmt - > with_check )
{
RangeTblEntry * rte ;
@ -695,7 +694,7 @@ AlterPolicy(AlterPolicyStmt *stmt)
with_check_qual = transformWhereClause ( with_check_pstate ,
copyObject ( stmt - > with_check ) ,
EXPR_KIND_WHERE ,
" ROW SECURIT Y" ) ;
" POLIC Y" ) ;
with_check_parse_rtable = with_check_pstate - > p_rtable ;
free_parsestate ( with_check_pstate ) ;
@ -707,28 +706,28 @@ AlterPolicy(AlterPolicyStmt *stmt)
memset ( isnull , 0 , sizeof ( isnull ) ) ;
/* Find policy to update. */
pg_rowsecurit y_rel = heap_open ( RowSecurit yRelationId, RowExclusiveLock ) ;
pg_polic y_rel = heap_open ( Polic yRelationId, RowExclusiveLock ) ;
/* Set key - row security relation id. */
/* Set key - policy's relation id. */
ScanKeyInit ( & skey [ 0 ] ,
Anum_pg_rowsecurity_rsec relid ,
Anum_pg_policy_pol relid ,
BTEqualStrategyNumber , F_OIDEQ ,
ObjectIdGetDatum ( table_id ) ) ;
/* Set key - row security policy name. */
/* Set key - policy's name. */
ScanKeyInit ( & skey [ 1 ] ,
Anum_pg_rowsecurity_rsec polname ,
Anum_pg_policy_ polname ,
BTEqualStrategyNumber , F_NAMEEQ ,
CStringGetDatum ( stmt - > policy_name ) ) ;
sscan = systable_beginscan ( pg_rowsecurit y_rel ,
RowSecurityR elidPolnameIndexId, true , NULL , 2 ,
sscan = systable_beginscan ( pg_polic y_rel ,
PolicyPolr elidPolnameIndexId, true , NULL , 2 ,
skey ) ;
rsec _tuple = systable_getnext ( sscan ) ;
policy _tuple = systable_getnext ( sscan ) ;
/* Check that the policy is found, raise an error if not. */
if ( ! HeapTupleIsValid ( rsec _tuple) )
if ( ! HeapTupleIsValid ( policy _tuple) )
ereport ( ERROR ,
( errcode ( ERRCODE_UNDEFINED_OBJECT ) ,
errmsg ( " policy \" %s \" on table \" %s \" does not exist " ,
@ -736,18 +735,18 @@ AlterPolicy(AlterPolicyStmt *stmt)
RelationGetRelationName ( target_table ) ) ) ) ;
/* Get policy command */
cmd_datum = heap_getattr ( rsec_tuple , Anum_pg_rowsecurity_rsec cmd,
RelationGetDescr ( pg_rowsecurit y_rel ) ,
& rsec cmd_isnull) ;
if ( rsec cmd_isnull)
rsec cmd = 0 ;
cmd_datum = heap_getattr ( policy_tuple , Anum_pg_policy_pol cmd,
RelationGetDescr ( pg_polic y_rel ) ,
& pol cmd_isnull) ;
if ( pol cmd_isnull)
pol cmd = 0 ;
else
rsec cmd = DatumGetChar ( cmd_datum ) ;
pol cmd = DatumGetChar ( cmd_datum ) ;
/*
* If the command is SELECT or DELETE then WITH CHECK should be NULL .
*/
if ( ( rsec cmd = = ACL_SELECT_CHR | | rsec cmd = = ACL_DELETE_CHR )
if ( ( pol cmd = = ACL_SELECT_CHR | | pol cmd = = ACL_DELETE_CHR )
& & stmt - > with_check ! = NULL )
ereport ( ERROR ,
( errcode ( ERRCODE_SYNTAX_ERROR ) ,
@ -757,52 +756,52 @@ AlterPolicy(AlterPolicyStmt *stmt)
* If the command is INSERT then WITH CHECK should be the only
* expression provided .
*/
if ( ( rsec cmd = = ACL_INSERT_CHR )
if ( ( pol cmd = = ACL_INSERT_CHR )
& & stmt - > qual ! = NULL )
ereport ( ERROR ,
( errcode ( ERRCODE_SYNTAX_ERROR ) ,
errmsg ( " only WITH CHECK expression allowed for INSERT " ) ) ) ;
rowsec _id = HeapTupleGetOid ( rsec _tuple) ;
policy _id = HeapTupleGetOid ( policy _tuple) ;
if ( role_ids ! = NULL )
{
replaces [ Anum_pg_rowsecurity_rsec roles - 1 ] = true ;
values [ Anum_pg_rowsecurity_rsec roles - 1 ] = PointerGetDatum ( role_ids ) ;
replaces [ Anum_pg_policy_pol roles - 1 ] = true ;
values [ Anum_pg_policy_pol roles - 1 ] = PointerGetDatum ( role_ids ) ;
}
if ( qual ! = NULL )
{
replaces [ Anum_pg_rowsecurity_rsec qual - 1 ] = true ;
values [ Anum_pg_rowsecurity_rsec qual - 1 ]
replaces [ Anum_pg_policy_pol qual - 1 ] = true ;
values [ Anum_pg_policy_pol qual - 1 ]
= CStringGetTextDatum ( nodeToString ( qual ) ) ;
}
if ( with_check_qual ! = NULL )
{
replaces [ Anum_pg_rowsecurity_rsec withcheck - 1 ] = true ;
values [ Anum_pg_rowsecurity_rsec withcheck - 1 ]
replaces [ Anum_pg_policy_pol withcheck - 1 ] = true ;
values [ Anum_pg_policy_pol withcheck - 1 ]
= CStringGetTextDatum ( nodeToString ( with_check_qual ) ) ;
}
new_tuple = heap_modify_tuple ( rsec _tuple,
RelationGetDescr ( pg_rowsecurit y_rel ) ,
new_tuple = heap_modify_tuple ( policy _tuple,
RelationGetDescr ( pg_polic y_rel ) ,
values , isnull , replaces ) ;
simple_heap_update ( pg_rowsecurit y_rel , & new_tuple - > t_self , new_tuple ) ;
simple_heap_update ( pg_polic y_rel , & new_tuple - > t_self , new_tuple ) ;
/* Update Catalog Indexes */
CatalogUpdateIndexes ( pg_rowsecurit y_rel , new_tuple ) ;
CatalogUpdateIndexes ( pg_polic y_rel , new_tuple ) ;
/* Update Dependencies. */
deleteDependencyRecordsFor ( RowSecurityRelationId , rowsec _id, false ) ;
deleteDependencyRecordsFor ( PolicyRelationId , policy _id, false ) ;
/* Record Dependencies */
target . classId = RelationRelationId ;
target . objectId = table_id ;
target . objectSubId = 0 ;
myself . classId = RowSecurit yRelationId;
myself . objectId = rowsec _id;
myself . classId = Polic yRelationId;
myself . objectId = policy _id;
myself . objectSubId = 0 ;
recordDependencyOn ( & myself , & target , DEPENDENCY_AUTO ) ;
@ -820,9 +819,9 @@ AlterPolicy(AlterPolicyStmt *stmt)
/* Clean up. */
systable_endscan ( sscan ) ;
relation_close ( target_table , NoLock ) ;
heap_close ( pg_rowsecurit y_rel , RowExclusiveLock ) ;
heap_close ( pg_polic y_rel , RowExclusiveLock ) ;
return rowsec _id;
return policy _id;
}
/*
@ -832,13 +831,13 @@ AlterPolicy(AlterPolicyStmt *stmt)
Oid
rename_policy ( RenameStmt * stmt )
{
Relation pg_rowsecurit y_rel ;
Relation pg_polic y_rel ;
Relation target_table ;
Oid table_id ;
Oid opoloid ;
ScanKeyData skey [ 2 ] ;
SysScanDesc sscan ;
HeapTuple rsec _tuple;
HeapTuple policy _tuple;
/* Get id of table. Also handles permissions checks. */
table_id = RangeVarGetRelidExtended ( stmt - > relation , AccessExclusiveLock ,
@ -848,74 +847,74 @@ rename_policy(RenameStmt *stmt)
target_table = relation_open ( table_id , NoLock ) ;
pg_rowsecurit y_rel = heap_open ( RowSecurit yRelationId, RowExclusiveLock ) ;
pg_polic y_rel = heap_open ( Polic yRelationId, RowExclusiveLock ) ;
/* First pass -- check for conflict */
/* Add key - row security relation id. */
/* Add key - policy's relation id. */
ScanKeyInit ( & skey [ 0 ] ,
Anum_pg_rowsecurity_rsec relid ,
Anum_pg_policy_pol relid ,
BTEqualStrategyNumber , F_OIDEQ ,
ObjectIdGetDatum ( table_id ) ) ;
/* Add key - row security policy name. */
/* Add key - policy's name. */
ScanKeyInit ( & skey [ 1 ] ,
Anum_pg_rowsecurity_rsec polname ,
Anum_pg_policy_ polname ,
BTEqualStrategyNumber , F_NAMEEQ ,
CStringGetDatum ( stmt - > newname ) ) ;
sscan = systable_beginscan ( pg_rowsecurit y_rel ,
RowSecurityR elidPolnameIndexId, true , NULL , 2 ,
sscan = systable_beginscan ( pg_polic y_rel ,
PolicyPolr elidPolnameIndexId, true , NULL , 2 ,
skey ) ;
if ( HeapTupleIsValid ( systable_getnext ( sscan ) ) )
ereport ( ERROR ,
( errcode ( ERRCODE_DUPLICATE_OBJECT ) ,
errmsg ( " row- policy \" %s \" for table \" %s \" already exists " ,
errmsg ( " policy \" %s \" for table \" %s \" already exists " ,
stmt - > newname , RelationGetRelationName ( target_table ) ) ) ) ;
systable_endscan ( sscan ) ;
/* Second pass -- find existing policy and update */
/* Add key - row security relation id. */
/* Add key - policy's relation id. */
ScanKeyInit ( & skey [ 0 ] ,
Anum_pg_rowsecurity_rsec relid ,
Anum_pg_policy_pol relid ,
BTEqualStrategyNumber , F_OIDEQ ,
ObjectIdGetDatum ( table_id ) ) ;
/* Add key - row security policy name. */
/* Add key - policy's name. */
ScanKeyInit ( & skey [ 1 ] ,
Anum_pg_rowsecurity_rsec polname ,
Anum_pg_policy_ polname ,
BTEqualStrategyNumber , F_NAMEEQ ,
CStringGetDatum ( stmt - > subname ) ) ;
sscan = systable_beginscan ( pg_rowsecurit y_rel ,
RowSecurityR elidPolnameIndexId, true , NULL , 2 ,
sscan = systable_beginscan ( pg_polic y_rel ,
PolicyPolr elidPolnameIndexId, true , NULL , 2 ,
skey ) ;
rsec _tuple = systable_getnext ( sscan ) ;
policy _tuple = systable_getnext ( sscan ) ;
/* Complain if we did not find the policy */
if ( ! HeapTupleIsValid ( rsec _tuple) )
if ( ! HeapTupleIsValid ( policy _tuple) )
ereport ( ERROR ,
( errcode ( ERRCODE_UNDEFINED_OBJECT ) ,
errmsg ( " row- policy \" %s \" for table \" %s \" does not exist " ,
errmsg ( " policy \" %s \" for table \" %s \" does not exist " ,
stmt - > subname , RelationGetRelationName ( target_table ) ) ) ) ;
opoloid = HeapTupleGetOid ( rsec _tuple) ;
opoloid = HeapTupleGetOid ( policy _tuple) ;
rsec _tuple = heap_copytuple ( rsec _tuple) ;
policy _tuple = heap_copytuple ( policy _tuple) ;
namestrcpy ( & ( ( Form_pg_rowsecurit y ) GETSTRUCT ( rsec _tuple) ) - > rsec polname,
namestrcpy ( & ( ( Form_pg_polic y ) GETSTRUCT ( policy _tuple) ) - > polname ,
stmt - > newname ) ;
simple_heap_update ( pg_rowsecurity_rel , & rsec _tuple - > t_self , rsec _tuple) ;
simple_heap_update ( pg_policy_rel , & policy _tuple - > t_self , policy _tuple) ;
/* keep system catalog indexes current */
CatalogUpdateIndexes ( pg_rowsecurity_rel , rsec _tuple ) ;
CatalogUpdateIndexes ( pg_policy_rel , policy _tuple ) ;
InvokeObjectPostAlterHook ( RowSecurit yRelationId,
HeapTupleGetOid ( rsec _tuple) , 0 ) ;
InvokeObjectPostAlterHook ( Polic yRelationId,
HeapTupleGetOid ( policy _tuple) , 0 ) ;
/*
* Invalidate relation ' s relcache entry so that other backends ( and
@ -926,7 +925,7 @@ rename_policy(RenameStmt *stmt)
/* Clean up. */
systable_endscan ( sscan ) ;
heap_close ( pg_rowsecurit y_rel , RowExclusiveLock ) ;
heap_close ( pg_polic y_rel , RowExclusiveLock ) ;
relation_close ( target_table , NoLock ) ;
return opoloid ;
@ -941,33 +940,33 @@ rename_policy(RenameStmt *stmt)
Oid
get_relation_policy_oid ( Oid relid , const char * policy_name , bool missing_ok )
{
Relation pg_rowsecurit y_rel ;
Relation pg_polic y_rel ;
ScanKeyData skey [ 2 ] ;
SysScanDesc sscan ;
HeapTuple rsec _tuple;
HeapTuple policy _tuple;
Oid policy_oid ;
pg_rowsecurit y_rel = heap_open ( RowSecurit yRelationId, AccessShareLock ) ;
pg_polic y_rel = heap_open ( Polic yRelationId, AccessShareLock ) ;
/* Add key - row security relation id. */
/* Add key - policy's relation id. */
ScanKeyInit ( & skey [ 0 ] ,
Anum_pg_rowsecurity_rsec relid ,
Anum_pg_policy_pol relid ,
BTEqualStrategyNumber , F_OIDEQ ,
ObjectIdGetDatum ( relid ) ) ;
/* Add key - row security policy name. */
/* Add key - policy's name. */
ScanKeyInit ( & skey [ 1 ] ,
Anum_pg_rowsecurity_rsec polname ,
Anum_pg_policy_ polname ,
BTEqualStrategyNumber , F_NAMEEQ ,
CStringGetDatum ( policy_name ) ) ;
sscan = systable_beginscan ( pg_rowsecurit y_rel ,
RowSecurityR elidPolnameIndexId, true , NULL , 2 ,
sscan = systable_beginscan ( pg_polic y_rel ,
PolicyPolr elidPolnameIndexId, true , NULL , 2 ,
skey ) ;
rsec _tuple = systable_getnext ( sscan ) ;
policy _tuple = systable_getnext ( sscan ) ;
if ( ! HeapTupleIsValid ( rsec _tuple) )
if ( ! HeapTupleIsValid ( policy _tuple) )
{
if ( ! missing_ok )
ereport ( ERROR ,
@ -978,11 +977,11 @@ get_relation_policy_oid(Oid relid, const char *policy_name, bool missing_ok)
policy_oid = InvalidOid ;
}
else
policy_oid = HeapTupleGetOid ( rsec _tuple) ;
policy_oid = HeapTupleGetOid ( policy _tuple) ;
/* Clean up. */
systable_endscan ( sscan ) ;
heap_close ( pg_rowsecurit y_rel , AccessShareLock ) ;
heap_close ( pg_polic y_rel , AccessShareLock ) ;
return policy_oid ;
}