SEPostgreSQL Abstraction

From PostgreSQL wiki
Jump to navigationJump to search

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.

pg_attribute objects

pg_proc objects

pg_language objects

pg_tablespace objects

pg_foreign_data_wrapper objects

pg_foreign_server objects

pg_type objects

pg_oper objects

pg_opclass objects

pg_opfamily objects

pg_conversion objects

pg_ts_dict objects

pg_ts_config objects

pg_ts_parser objects

pg_ts_template objects