SEPostgreSQL Abstraction
This wikipage introduces a new abstraction layer to implement access control features.
Overview
Nowadays, we have various kind of security models which can be applied on accesses to database objects.
The native database privilege mechanism is also one of the security models. It makes its access control decision based on the database roles and the ACL (access control list) of the database objects to be accessed.
On the other hand, we currently have SE-PostgreSQL which is proposed as a different approach to control accesses to database objects, based on another security model. It makes its access control decision based on a couple of security contexts and the security policy in kernel.
Both of security features has same purpose which is to control accesses to database obejcts using SQL queries. But their criterions are not identical.
Historically, the native database privilege is the only security model in PostgreSQL. So, its logic has been hard-coded on the core routines (such as DefineRelation) directry, and it also requires the second security model to put its security hooks various kind of core routines.
However, fundamentally, the core routines should focues on whether the required operation is allowed by the security mechanism, or not. It is a separatable issue how the required operation is allowed.
The series of functions provides an abstraction layer to focus on what to be checked. For example, the native database privilege requires the database role to be the owner of the table when it is modified with ALTER TABLE. On the other hand, SELinux requires the db_table:{setattr} should be allowed on the target table. The security_class_alter_table invokes both of security model to check. The way to make its decision is encapsulated within the abstraction layer.
References
Regular DMLs
security_table_permissions
void security_table_permissions(Oid table_oid, Oid user_id, AclMode required_perms, Bitmapset selected_cols, Bitmapset modified_cols); table_oid : OID of the target relation user_id : OID of the database role to be checked required_perms : Bitmask of the database privileges (e.g, ACL_SELECT) selected_cols : Bitmap of the referenced columns modified_cols : Bitmap of the modified columns
This checks permissions on the target table and columns which are referenced or modified, then raises an error, if violated.
It should be invoked instead of the ExecCheckRTEPerms(). In addition, it is also available on the COPY TO/FROM and SELECT INTO statement. Note that the native database privilege does not check INSERT permission on OpenIntoRel(), because it implicitly assumes the table owner can always insert tuples into the new table. However, it should be fundamentally checked.
pg_database objects
security_database_create
Datum security_database_create(const char *database_name, Oid dat_owner, Oid tblspc_oid, DefElem *given_secon); database_name : Name of the new database in creation dat_owner : OID of the new database owner tablespace_id : OID of the tablespace given_secon : User given security context, if exist
This checks permissions to create a new database, then raises an error if violated. It returns a security context to be assigned on the new database, if exist.
The native database privilege checks have_createdb_privilege(), the membership of the owner and ACL_CREATE on the tablespace.
security_database_alter
Datum security_database_alter(Oid database_oid, const char *new_name, Oit tblspc_oid, Oid new_owner, DefElem *given_secon); database_oid : OID of the database to be altered new_name : The new name of the database, if given tblspc_oid : The new tablespace of the database, if given new_owner : The new owner of the database, if given given_secon : The new security context of the database, if given
This checks permissions to alter a certain database, then raises an error if violated. It returns a security context to be assigned on the database, if given_secon is not NULL.
The native database privilege checks ownership of the database and corresponding permissions depending on ALTER options.
security_database_drop
void security_database_drop(Oid database_oid); database_oid : OID of the database to be dropped
This checks permissions to drop a certain database, then raises an error if violated.
The native database privilege checks ownership of the database.
security_database_connect
void security_database_connect(Oid database_oid) datbase_oid : OID of the database to be connected
This checks permissions to connect a certain database.
The native database privilege check ACL_CONNECT on the database.
security_database_reindex
void security_database_reindex(Oid database_oid) database_oid : OID of the database to be reindexed
This checks permissions to reindex relations on a certain database.
The native database privilege checks ownership of the database.
security_database_comment
void security_database_comment(Oid database_oid) database_oid : OID of the database to be commented
This checks permissions to comment on a certain database.
The native database privilege checks ownership of the database.
pg_namespace objects
security_namespace_create
Datum security_namespace_create(bool is_temp, DefElem *given_secon) is_temp : true, if temporary namespace given_secon : User given security context, if exist
This checks permissions to create a new schema, then raises an error if violated. It returns a security context to be assigned on the new namespace, if exist.
The native database privilege checks ACL_CREATE or ACL_CREATE_TEMP on the database.
security_namespace_alter
Datum security_namespace_alter(Oid namespace_oid, const char *new_name, Oid new_owner, DefElem *given_secon) namespace_oid : OID of the namespace to be altered new_name : The new name of the namespace, if given new_owner : The new owner of the namespace, if given given_secon : The new security context of the namespace, if given
This checks permission to alter a certain namespace, then it raises an error if violated. It returns a security context to be assigned on the namespace, if given_secon is not NULL.
The native database privilege checks ownership of the namespace and ACL_CREATE on the database. (Renaming pg_temp is not allowed due to the hardwired rule.)
security_namespace_drop
void security_namespace_drop(Oid namespace_oid) namespace_oid : OID of the namespace to be dropped
This checks permission to drop a certain namespace, then it raises an error if violated.
The native database privilege checks ownership of the namespace.
security_namespace_search
bool security_namespace_search(Oid namespace_oid) namespace_oid : OID of the namespace to be searched at.
This checks permission to search at a certain namespace, then it raises an error if violated.
The native database privilege checks ACL_USAGE of the namespace.
security_namespace_comment
void security_namespace_comment(Oid namespace_oid) namespace_oid : OID of the namespace to be commented on.
This checks permission to comment on a certain namespace, then it raises an error if violated.
The native database privilege checks ownership of the namespace.
pg_class objects
security_class_create
Datum *security_class_create(TupleDesc *tupdesc, const char *rel_name, char relkind, Oid rel_owner, Oid rel_tblspc, Oid rel_nspid, CreateStmt *stmt); tupdesc : TupleDesc object of the new relation in creation rel_name : Name of the new relation in creation rel_kind : Relkind of the new relation rel_owner : OID of the relation owner rel_tblspc : OID of the tablespace rel_nspid : OID of the namespace stmt : CreateStmt object, if exists.
This checks permissions to create a new table and columns, then raises an error if violated. It returns an array of security context to be assigned on the new table and columns. If the given relkind does not requires permission checks (such as RELKIND_TOASTVALUE), it just returns an array of the security contexts.
The native database privilege checks ACL_CREATE on the namespace and ACL_CREATE on the tablespace (if not default one).
security_class_create_copy
Datum *security_class_create_copy(Relation relation); relation : relation of the source relation
This does not check anything, but returns an array of security context to be assigned on the new temporay table created by make_new_heap(). The temporary table is used to implement table-rewriting, so the table needs to have identical security contexts.
security_class_create_inherit
void security_class_create_inherit(Relation parent); parent : relation of the parent relation
This checks permission to create a child function which inherits a certain table, then raises an error if violated.
The native database privilege checks the ownership of the parent table.
security_class_alter
Datum security_class_alter(Oid relid, const char *new_name, Oid new_owner, Oid new_tblspc, Oid new_nspid, DefElem *new_secon); relid : OID of the relation to be altered new_name : New name of the relation, if given new_owner : New owner of the relation, if given new_tblspc : New tablespace of the relation, if given new_nspid : New namespace of the relation, if given new_secon : New security context of the relation, if given
This checks permissions to alter a certain table, then raises an error if violated. It returns a security context to be assigned on the table, if new_secon is not NULL.
The native database privilege checks the ownership of the relation, and corresponding permissions depending on the options.
security_class_drop
void security_class_drop(Oid relid); relid : OID of the relation to be dropped
This checks permissions to drop a certain table, then raises an error if violated.
The native database privilege checks the ownership of the relation.
security_class_lock
void security_class_lock(Oid relid, LOCKMODE lockmode); relid : OID of the relation to be locked lockmode : required lock mode
This checks permissions to lock a certain table using LOCK command, then raises an error if violated.
The native database privilege checks either ACL_SELECT for AccessShareLock or ACL_UPDATE | ACL_DELETE | ACL_TRUNCATE for other lockmode.
security_class_trigger
void security_class_trigger(Oid relid, Oid constrrelid, Oid func_oid); relid : OID of the relation on which the new trigger is set consrelid : OID of the relation which is constrained by the new trigger func_oid : OID of the trigger function
This checks permissions to create a trigger function on a certain table, then raises an error if violated.
The native database privilege checks ACL_TRIGGER on the relations.
security_class_reference
void security_class_reference(Oid relid, int16 *attnums, int natts); relid : OID of the relation on which FK constraint is set attnums : An arrary of attribute numbers natts : The length of attnums array
This checks permission to create a foreign key constraint on a certain table, then raises an error if violated.
The native database privilege checks ACL_REFERENCE on the relations.
security_class_truncate
void security_class_truncate(Relation rel) rel : Relation to be truncated
This checks permission to truncate a certain table, then raises an error if violated.
The native database privilege checks ACL_TRUNCATE on the relation.
security_class_reindex
void security_class_reindex(Oid relid) relid : OID of the index to be reindexed
This checks permission to reindex indexes on a certain table or a certain index, then raises an error if violated.
The native database privilege checks ownership of the table.
security_class_vacuum
bool security_class_vacuum(Relation vacuum_rel) vacuum_rel : The relation to be vacuumed
This checks permissions to vacuum a certain relation, then it returns false, then raises an error if violated.
The native database privilege checks either ownership of the relation or the database if not shared relation.
security_class_get_tid
void security_class_get_tid(Oid relid);
This checks permissions to get the current transaction identifier on a certain relation, then raises an error if violated.
The native database privilege checks ACL_SELECT on the relation.
security_class_get_value
void security_class_get_value(Oid relid); relid : OID of the sequence to be referenced
This checks permission to refer the current value of a certain sequence objects, then raises an error if violated.
The native database privilege checks either of ACL_SELECT or ACL_USAGE on the sequence object.
security_class_next_value
void security_class_next_value(Oid relid); relid : OID of the sequence to be fetched
This checks permission to fetch the next value of a certain sequence objects, then raises an error if violated.
The native database privilege checks either of ACL_UPDATE or ACL_USAGE on the sequence object.
security_class_set_value
void security_class_set_value(Oid relid); relid : OID of the sequence to be set a new value.
This checks permisson to set a descretional value of a certain sequence objects, then raises an error if violated.
The native database privilege checks ACL_UPDATE on the sequence object.