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.

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.

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

pg_namespace objects

security_namespace_create

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.

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

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

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.

security_class_lock

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.