diff options
Diffstat (limited to 'src/include')
-rw-r--r-- | src/include/catalog/catversion.h | 2 | ||||
-rw-r--r-- | src/include/catalog/dependency.h | 1 | ||||
-rw-r--r-- | src/include/catalog/indexing.h | 6 | ||||
-rw-r--r-- | src/include/catalog/pg_authid.h | 12 | ||||
-rw-r--r-- | src/include/catalog/pg_class.h | 24 | ||||
-rw-r--r-- | src/include/catalog/pg_rowsecurity.h | 53 | ||||
-rw-r--r-- | src/include/commands/policy.h | 33 | ||||
-rw-r--r-- | src/include/miscadmin.h | 1 | ||||
-rw-r--r-- | src/include/nodes/nodes.h | 2 | ||||
-rw-r--r-- | src/include/nodes/parsenodes.h | 33 | ||||
-rw-r--r-- | src/include/nodes/plannodes.h | 3 | ||||
-rw-r--r-- | src/include/nodes/relation.h | 3 | ||||
-rw-r--r-- | src/include/optimizer/planmain.h | 3 | ||||
-rw-r--r-- | src/include/parser/kwlist.h | 1 | ||||
-rw-r--r-- | src/include/rewrite/rowsecurity.h | 80 | ||||
-rw-r--r-- | src/include/utils/acl.h | 2 | ||||
-rw-r--r-- | src/include/utils/plancache.h | 4 | ||||
-rw-r--r-- | src/include/utils/rel.h | 2 |
18 files changed, 247 insertions, 18 deletions
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index a36dbeb80b..af0475e831 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 201409162 +#define CATALOG_VERSION_NO 201409191 #endif diff --git a/src/include/catalog/dependency.h b/src/include/catalog/dependency.h index 8ed259283a..6a4913a66e 100644 --- a/src/include/catalog/dependency.h +++ b/src/include/catalog/dependency.h @@ -147,6 +147,7 @@ typedef enum ObjectClass OCLASS_DEFACL, /* pg_default_acl */ OCLASS_EXTENSION, /* pg_extension */ OCLASS_EVENT_TRIGGER, /* pg_event_trigger */ + OCLASS_ROWSECURITY, /* pg_rowsecurity */ MAX_OCLASS /* MUST BE LAST */ } ObjectClass; diff --git a/src/include/catalog/indexing.h b/src/include/catalog/indexing.h index 59576fd751..870692cf54 100644 --- a/src/include/catalog/indexing.h +++ b/src/include/catalog/indexing.h @@ -299,6 +299,12 @@ DECLARE_UNIQUE_INDEX(pg_extension_name_index, 3081, on pg_extension using btree( DECLARE_UNIQUE_INDEX(pg_range_rngtypid_index, 3542, on pg_range using btree(rngtypid oid_ops)); #define RangeTypidIndexId 3542 +DECLARE_UNIQUE_INDEX(pg_rowsecurity_oid_index, 3257, on pg_rowsecurity using btree(oid oid_ops)); +#define RowSecurityOidIndexId 3257 + +DECLARE_UNIQUE_INDEX(pg_rowsecurity_polname_relid_index, 3258, on pg_rowsecurity using btree(rsecrelid oid_ops, rsecpolname name_ops)); +#define RowSecurityRelidPolnameIndexId 3258 + /* last step of initialization script: build the indexes declared above */ BUILD_INDICES diff --git a/src/include/catalog/pg_authid.h b/src/include/catalog/pg_authid.h index e7c32c9fa6..3b63d2bb9e 100644 --- a/src/include/catalog/pg_authid.h +++ b/src/include/catalog/pg_authid.h @@ -52,6 +52,7 @@ CATALOG(pg_authid,1260) BKI_SHARED_RELATION BKI_ROWTYPE_OID(2842) BKI_SCHEMA_MAC bool rolcatupdate; /* allowed to alter catalogs manually? */ bool rolcanlogin; /* allowed to log in as session user? */ bool rolreplication; /* role used for streaming replication */ + bool rolbypassrls; /* allowed to bypass row level security? */ int32 rolconnlimit; /* max connections allowed (-1=no limit) */ /* remaining fields may be null; use heap_getattr to read them! */ @@ -73,7 +74,7 @@ typedef FormData_pg_authid *Form_pg_authid; * compiler constants for pg_authid * ---------------- */ -#define Natts_pg_authid 11 +#define Natts_pg_authid 12 #define Anum_pg_authid_rolname 1 #define Anum_pg_authid_rolsuper 2 #define Anum_pg_authid_rolinherit 3 @@ -82,9 +83,10 @@ typedef FormData_pg_authid *Form_pg_authid; #define Anum_pg_authid_rolcatupdate 6 #define Anum_pg_authid_rolcanlogin 7 #define Anum_pg_authid_rolreplication 8 -#define Anum_pg_authid_rolconnlimit 9 -#define Anum_pg_authid_rolpassword 10 -#define Anum_pg_authid_rolvaliduntil 11 +#define Anum_pg_authid_rolbypassrls 9 +#define Anum_pg_authid_rolconnlimit 10 +#define Anum_pg_authid_rolpassword 11 +#define Anum_pg_authid_rolvaliduntil 12 /* ---------------- * initial contents of pg_authid @@ -93,7 +95,7 @@ typedef FormData_pg_authid *Form_pg_authid; * user choices. * ---------------- */ -DATA(insert OID = 10 ( "POSTGRES" t t t t t t t -1 _null_ _null_ )); +DATA(insert OID = 10 ( "POSTGRES" t t t t t t t t -1 _null_ _null_)); #define BOOTSTRAP_SUPERUSERID 10 diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h index f2fb317e5f..f6353514ca 100644 --- a/src/include/catalog/pg_class.h +++ b/src/include/catalog/pg_class.h @@ -65,6 +65,7 @@ CATALOG(pg_class,1259) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83) BKI_SCHEMA_MACRO bool relhasrules; /* has (or has had) any rules */ bool relhastriggers; /* has (or has had) any TRIGGERs */ bool relhassubclass; /* has (or has had) derived classes */ + bool relhasrowsecurity; /* has (or has had) row-security policy */ bool relispopulated; /* matview currently holds query results */ char relreplident; /* see REPLICA_IDENTITY_xxx constants */ TransactionId relfrozenxid; /* all Xids < this are frozen in this rel */ @@ -94,7 +95,7 @@ typedef FormData_pg_class *Form_pg_class; * ---------------- */ -#define Natts_pg_class 29 +#define Natts_pg_class 30 #define Anum_pg_class_relname 1 #define Anum_pg_class_relnamespace 2 #define Anum_pg_class_reltype 3 @@ -118,12 +119,13 @@ typedef FormData_pg_class *Form_pg_class; #define Anum_pg_class_relhasrules 21 #define Anum_pg_class_relhastriggers 22 #define Anum_pg_class_relhassubclass 23 -#define Anum_pg_class_relispopulated 24 -#define Anum_pg_class_relreplident 25 -#define Anum_pg_class_relfrozenxid 26 -#define Anum_pg_class_relminmxid 27 -#define Anum_pg_class_relacl 28 -#define Anum_pg_class_reloptions 29 +#define Anum_pg_class_relhasrowsecurity 24 +#define Anum_pg_class_relispopulated 25 +#define Anum_pg_class_relreplident 26 +#define Anum_pg_class_relfrozenxid 27 +#define Anum_pg_class_relminmxid 28 +#define Anum_pg_class_relacl 29 +#define Anum_pg_class_reloptions 30 /* ---------------- * initial contents of pg_class @@ -138,13 +140,13 @@ typedef FormData_pg_class *Form_pg_class; * Note: "3" in the relfrozenxid column stands for FirstNormalTransactionId; * similarly, "1" in relminmxid stands for FirstMultiXactId */ -DATA(insert OID = 1247 ( pg_type PGNSP 71 0 PGUID 0 0 0 0 0 0 0 f f p r 30 0 t f f f f t n 3 1 _null_ _null_ )); +DATA(insert OID = 1247 ( pg_type PGNSP 71 0 PGUID 0 0 0 0 0 0 0 f f p r 30 0 t f f f f f t n 3 1 _null_ _null_ )); DESCR(""); -DATA(insert OID = 1249 ( pg_attribute PGNSP 75 0 PGUID 0 0 0 0 0 0 0 f f p r 21 0 f f f f f t n 3 1 _null_ _null_ )); +DATA(insert OID = 1249 ( pg_attribute PGNSP 75 0 PGUID 0 0 0 0 0 0 0 f f p r 21 0 f f f f f f t n 3 1 _null_ _null_ )); DESCR(""); -DATA(insert OID = 1255 ( pg_proc PGNSP 81 0 PGUID 0 0 0 0 0 0 0 f f p r 27 0 t f f f f t n 3 1 _null_ _null_ )); +DATA(insert OID = 1255 ( pg_proc PGNSP 81 0 PGUID 0 0 0 0 0 0 0 f f p r 27 0 t f f f f f t n 3 1 _null_ _null_ )); DESCR(""); -DATA(insert OID = 1259 ( pg_class PGNSP 83 0 PGUID 0 0 0 0 0 0 0 f f p r 29 0 t f f f f t n 3 1 _null_ _null_ )); +DATA(insert OID = 1259 ( pg_class PGNSP 83 0 PGUID 0 0 0 0 0 0 0 f f p r 30 0 t f f f f f t n 3 1 _null_ _null_ )); DESCR(""); diff --git a/src/include/catalog/pg_rowsecurity.h b/src/include/catalog/pg_rowsecurity.h new file mode 100644 index 0000000000..2638d5e684 --- /dev/null +++ b/src/include/catalog/pg_rowsecurity.h @@ -0,0 +1,53 @@ +/* + * pg_rowsecurity.h + * definition of the system catalog for row-security policy (pg_rowsecurity) + * + * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + */ +#ifndef PG_ROWSECURITY_H +#define PG_ROWSECURITY_H + +#include "catalog/genbki.h" + +/* ---------------- + * pg_rowsecurity definition. cpp turns this into + * typedef struct FormData_pg_rowsecurity + * ---------------- + */ +#define RowSecurityRelationId 3256 + +CATALOG(pg_rowsecurity,3256) +{ + NameData rsecpolname; /* Policy name. */ + Oid rsecrelid; /* Oid of the relation with policy. */ + char rseccmd; /* One of ACL_*_CHR, or \0 for all */ + +#ifdef CATALOG_VARLEN + Oid rsecroles[1] /* Roles associated with policy, not-NULL */ + pg_node_tree rsecqual; /* Policy quals. */ + pg_node_tree rsecwithcheck; /* WITH CHECK quals. */ +#endif +} FormData_pg_rowsecurity; + +/* ---------------- + * Form_pg_rowsecurity corresponds to a pointer to a row with + * the format of pg_rowsecurity relation. + * ---------------- + */ +typedef FormData_pg_rowsecurity *Form_pg_rowsecurity; + +/* ---------------- + * compiler constants for pg_rowsecurity + * ---------------- + */ +#define Natts_pg_rowsecurity 6 +#define Anum_pg_rowsecurity_rsecpolname 1 +#define Anum_pg_rowsecurity_rsecrelid 2 +#define Anum_pg_rowsecurity_rseccmd 3 +#define Anum_pg_rowsecurity_rsecroles 4 +#define Anum_pg_rowsecurity_rsecqual 5 +#define Anum_pg_rowsecurity_rsecwithcheck 6 + +#endif /* PG_ROWSECURITY_H */ diff --git a/src/include/commands/policy.h b/src/include/commands/policy.h new file mode 100644 index 0000000000..95d8a6d117 --- /dev/null +++ b/src/include/commands/policy.h @@ -0,0 +1,33 @@ +/*------------------------------------------------------------------------- + * + * policy.h + * prototypes for policy.c. + * + * + * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * src/include/commands/policy.h + * + *------------------------------------------------------------------------- + */ + +#ifndef POLICY_H +#define POLICY_H + +#include "nodes/parsenodes.h" + +extern void RelationBuildRowSecurity(Relation relation); + +extern void RemovePolicyById(Oid policy_id); + +extern Oid CreatePolicy(CreatePolicyStmt *stmt); +extern Oid AlterPolicy(AlterPolicyStmt *stmt); + +Oid get_relation_policy_oid(Oid relid, + const char *policy_name, bool missing_ok); + +Oid rename_policy(RenameStmt *stmt); + + +#endif /* POLICY_H */ diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h index 3807955c8e..2ba98856ff 100644 --- a/src/include/miscadmin.h +++ b/src/include/miscadmin.h @@ -272,6 +272,7 @@ extern int trace_recovery(int trace_level); /* flags to be OR'd to form sec_context */ #define SECURITY_LOCAL_USERID_CHANGE 0x0001 #define SECURITY_RESTRICTED_OPERATION 0x0002 +#define SECURITY_ROW_LEVEL_DISABLED 0x0004 extern char *DatabasePath; diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h index a031b88b87..154d943d58 100644 --- a/src/include/nodes/nodes.h +++ b/src/include/nodes/nodes.h @@ -366,6 +366,8 @@ typedef enum NodeTag T_RefreshMatViewStmt, T_ReplicaIdentityStmt, T_AlterSystemStmt, + T_CreatePolicyStmt, + T_AlterPolicyStmt, /* * TAGS FOR PARSE TREE NODES (parsenodes.h) diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index d2c0b29c0d..f3aa69e4a1 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -120,6 +120,7 @@ typedef struct Query bool hasRecursive; /* WITH RECURSIVE was specified */ bool hasModifyingCTE; /* has INSERT/UPDATE/DELETE in WITH */ bool hasForUpdate; /* FOR [KEY] UPDATE/SHARE was specified */ + bool hasRowSecurity; /* Row-security policy is applied */ List *cteList; /* WITH list (of CommonTableExpr's) */ @@ -1224,6 +1225,7 @@ typedef enum ObjectType OBJECT_OPCLASS, OBJECT_OPERATOR, OBJECT_OPFAMILY, + OBJECT_POLICY, OBJECT_ROLE, OBJECT_RULE, OBJECT_SCHEMA, @@ -1333,6 +1335,8 @@ typedef enum AlterTableType AT_AddOf, /* OF <type_name> */ AT_DropOf, /* NOT OF */ AT_ReplicaIdentity, /* REPLICA IDENTITY */ + AT_EnableRowSecurity, /* ENABLE ROW SECURITY */ + AT_DisableRowSecurity, /* DISABLE ROW SECURITY */ AT_GenericOptions /* OPTIONS (...) */ } AlterTableType; @@ -1855,6 +1859,35 @@ typedef struct ImportForeignSchemaStmt List *options; /* list of options to pass to FDW */ } ImportForeignSchemaStmt; +/*---------------------- + * Create POLICY Statement + *---------------------- + */ +typedef struct CreatePolicyStmt +{ + NodeTag type; + char *policy_name; /* Policy's name */ + RangeVar *table; /* the table name the policy applies to */ + char *cmd; /* the command name the policy applies to */ + List *roles; /* the roles associated with the policy */ + Node *qual; /* the policy's condition */ + Node *with_check; /* the policy's WITH CHECK condition. */ +} CreatePolicyStmt; + +/*---------------------- + * Alter POLICY Statement + *---------------------- + */ +typedef struct AlterPolicyStmt +{ + NodeTag type; + char *policy_name; /* Policy's name */ + RangeVar *table; /* the table name the policy applies to */ + List *roles; /* the roles associated with the policy */ + Node *qual; /* the policy's condition */ + Node *with_check; /* the policy's WITH CHECK condition. */ +} AlterPolicyStmt; + /* ---------------------- * Create TRIGGER Statement * ---------------------- diff --git a/src/include/nodes/plannodes.h b/src/include/nodes/plannodes.h index 3b9c683829..18394946f8 100644 --- a/src/include/nodes/plannodes.h +++ b/src/include/nodes/plannodes.h @@ -67,6 +67,9 @@ typedef struct PlannedStmt List *invalItems; /* other dependencies, as PlanInvalItems */ int nParamExec; /* number of PARAM_EXEC Params used */ + + bool has_rls; /* row-security applied? */ + } PlannedStmt; /* macro for fetching the Plan associated with a SubPlan node */ diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h index dacbe9cc0b..f1a0504c0d 100644 --- a/src/include/nodes/relation.h +++ b/src/include/nodes/relation.h @@ -99,6 +99,9 @@ typedef struct PlannerGlobal Index lastRowMarkId; /* highest PlanRowMark ID assigned */ bool transientPlan; /* redo plan when TransactionXmin changes? */ + + bool has_rls; /* row-security is applied? */ + } PlannerGlobal; /* macro for fetching the Plan associated with a SubPlan node */ diff --git a/src/include/optimizer/planmain.h b/src/include/optimizer/planmain.h index 450425046a..3fdc2cba0e 100644 --- a/src/include/optimizer/planmain.h +++ b/src/include/optimizer/planmain.h @@ -135,6 +135,7 @@ extern void set_sa_opfuncid(ScalarArrayOpExpr *opexpr); extern void record_plan_function_dependency(PlannerInfo *root, Oid funcid); extern void extract_query_dependencies(Node *query, List **relationOids, - List **invalItems); + List **invalItems, + bool *hasRowSecurity); #endif /* PLANMAIN_H */ diff --git a/src/include/parser/kwlist.h b/src/include/parser/kwlist.h index 17888ad0ec..3c8c1b9e25 100644 --- a/src/include/parser/kwlist.h +++ b/src/include/parser/kwlist.h @@ -284,6 +284,7 @@ PG_KEYWORD("passing", PASSING, UNRESERVED_KEYWORD) PG_KEYWORD("password", PASSWORD, UNRESERVED_KEYWORD) PG_KEYWORD("placing", PLACING, RESERVED_KEYWORD) PG_KEYWORD("plans", PLANS, UNRESERVED_KEYWORD) +PG_KEYWORD("policy", POLICY, UNRESERVED_KEYWORD) PG_KEYWORD("position", POSITION, COL_NAME_KEYWORD) PG_KEYWORD("preceding", PRECEDING, UNRESERVED_KEYWORD) PG_KEYWORD("precision", PRECISION, COL_NAME_KEYWORD) diff --git a/src/include/rewrite/rowsecurity.h b/src/include/rewrite/rowsecurity.h new file mode 100644 index 0000000000..245005cae2 --- /dev/null +++ b/src/include/rewrite/rowsecurity.h @@ -0,0 +1,80 @@ +/* ------------------------------------------------------------------------- + * + * rowsecurity.h + * prototypes for optimizer/rowsecurity.c + * + * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * ------------------------------------------------------------------------- + */ +#ifndef ROWSECURITY_H +#define ROWSECURITY_H + +#include "nodes/execnodes.h" +#include "nodes/parsenodes.h" +#include "nodes/relation.h" +#include "utils/array.h" + +typedef struct RowSecurityPolicy +{ + Oid rsecid; + char *policy_name; + char cmd; + ArrayType *roles; + Expr *qual; + Expr *with_check_qual; + bool hassublinks; +} RowSecurityPolicy; + +typedef struct RowSecurityDesc +{ + MemoryContext rscxt; /* row-security memory context */ + List *policies; /* list of row-security policies */ +} RowSecurityDesc; + +/* GUC variable */ +extern int row_security; + +/* Possible values for row_security GUC */ +typedef enum RowSecurityConfigType +{ + ROW_SECURITY_OFF, + ROW_SECURITY_ON, + ROW_SECURITY_FORCE +} RowSecurityConfigType; + +/* + * Used by callers of check_enable_rls. + * + * RLS could be completely disabled on the tables involved in the query, + * which is the simple case, or it may depend on the current environment + * (the role which is running the query or the value of the row_security + * GUC- on, off, or force), or it might be simply enabled as usual. + * + * If RLS isn't on the table involved then RLS_NONE is returned to indicate + * that we don't need to worry about invalidating the query plan for RLS + * reasons. If RLS is on the table, but we are bypassing it for now, then + * we return RLS_NONE_ENV to indicate that, if the environment changes, + * we need to invalidate and replan. Finally, if RLS should be turned on + * for the query, then we return RLS_ENABLED, which means we also need to + * invalidate if the environment changes. + */ +enum CheckEnableRlsResult +{ + RLS_NONE, + RLS_NONE_ENV, + RLS_ENABLED +}; + +typedef List *(*row_security_policy_hook_type)(CmdType cmdtype, + Relation relation); + +extern PGDLLIMPORT row_security_policy_hook_type row_security_policy_hook; + +extern bool prepend_row_security_policies(Query* root, RangeTblEntry* rte, + int rt_index); + +extern int check_enable_rls(Oid relid, Oid checkAsUser); + +#endif /* ROWSECURITY_H */ diff --git a/src/include/utils/acl.h b/src/include/utils/acl.h index 9430baa4a0..a8e3164659 100644 --- a/src/include/utils/acl.h +++ b/src/include/utils/acl.h @@ -228,6 +228,7 @@ extern bool is_member_of_role_nosuper(Oid member, Oid role); extern bool is_admin_of_role(Oid member, Oid role); extern void check_is_member_of_role(Oid member, Oid role); extern Oid get_role_oid(const char *rolname, bool missing_ok); +extern Oid get_role_oid_or_public(const char *rolname); extern void select_best_grantor(Oid roleId, AclMode privileges, const Acl *acl, Oid ownerId, @@ -326,5 +327,6 @@ extern bool pg_foreign_server_ownercheck(Oid srv_oid, Oid roleid); extern bool pg_event_trigger_ownercheck(Oid et_oid, Oid roleid); extern bool pg_extension_ownercheck(Oid ext_oid, Oid roleid); extern bool has_createrole_privilege(Oid roleid); +extern bool has_bypassrls_privilege(Oid roleid); #endif /* ACL_H */ diff --git a/src/include/utils/plancache.h b/src/include/utils/plancache.h index cfbfaa26cc..56bf4bb7af 100644 --- a/src/include/utils/plancache.h +++ b/src/include/utils/plancache.h @@ -93,6 +93,7 @@ typedef struct CachedPlanSource List *invalItems; /* other dependencies, as PlanInvalItems */ struct OverrideSearchPath *search_path; /* search_path used for * parsing and planning */ + Oid planUserId; /* User-id that the plan depends on */ MemoryContext query_context; /* context holding the above, or NULL */ /* If we have a generic plan, this is a reference-counted link to it: */ struct CachedPlan *gplan; /* generic plan, or NULL if not valid */ @@ -108,6 +109,9 @@ typedef struct CachedPlanSource double generic_cost; /* cost of generic plan, or -1 if not known */ double total_custom_cost; /* total cost of custom plans so far */ int num_custom_plans; /* number of plans included in total */ + bool has_rls; /* planned with row-security? */ + int row_security_env; /* row security setting when planned */ + bool rowSecurityDisabled; /* is row-security disabled? */ } CachedPlanSource; /* diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h index 37b6cbbb4d..198b98f2f8 100644 --- a/src/include/utils/rel.h +++ b/src/include/utils/rel.h @@ -21,6 +21,7 @@ #include "fmgr.h" #include "nodes/bitmapset.h" #include "rewrite/prs2lock.h" +#include "rewrite/rowsecurity.h" #include "storage/block.h" #include "storage/relfilenode.h" #include "utils/relcache.h" @@ -105,6 +106,7 @@ typedef struct RelationData RuleLock *rd_rules; /* rewrite rules */ MemoryContext rd_rulescxt; /* private memory cxt for rd_rules, if any */ TriggerDesc *trigdesc; /* Trigger info, or NULL if rel has none */ + RowSecurityDesc *rsdesc; /* Row-security policy, or NULL */ /* data managed by RelationGetIndexList: */ List *rd_indexlist; /* list of OIDs of indexes on relation */ |