/* * sepgsql_proc_relabel * * It checks privileges to relabel the supplied function * by the `seclabel'. */ void sepgsql_proc_relabel(Oid functionId, const char *seclabel) { char *scontext = sepgsql_get_client_label(); char *tcontext; char *audit_name; audit_name = get_func_name(functionId); /* * check db_procedure:{setattr relabelfrom} permission */ tcontext = sepgsql_get_label(ProcedureRelationId, functionId, 0); sepgsql_check_perms(scontext, tcontext, SEPG_CLASS_DB_PROCEDURE, SEPG_DB_PROCEDURE__SETATTR | SEPG_DB_PROCEDURE__RELABELFROM, audit_name, true); pfree(tcontext); /* * check db_procedure:{relabelto} permission */ sepgsql_check_perms(scontext, seclabel, SEPG_CLASS_DB_PROCEDURE, SEPG_DB_PROCEDURE__RELABELTO, audit_name, true); pfree(audit_name); }
/* * sepgsql_relation_relabel * * It checks privileges to relabel the supplied relation by the `seclabel'. */ void sepgsql_relation_relabel(Oid relOid, const char *seclabel) { char *scontext = sepgsql_get_client_label(); char *tcontext; char *audit_name; char relkind; uint16_t tclass = 0; relkind = get_rel_relkind(relOid); if (relkind == RELKIND_RELATION) tclass = SEPG_CLASS_DB_TABLE; else if (relkind == RELKIND_SEQUENCE) tclass = SEPG_CLASS_DB_SEQUENCE; else if (relkind == RELKIND_VIEW) tclass = SEPG_CLASS_DB_VIEW; else ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("cannot set security labels on relations except " "for tables, sequences or views"))); audit_name = getObjectDescriptionOids(RelationRelationId, relOid); /* * check db_xxx:{setattr relabelfrom} permission */ tcontext = sepgsql_get_label(RelationRelationId, relOid, 0); sepgsql_check_perms(scontext, tcontext, tclass, SEPG_DB_TABLE__SETATTR | SEPG_DB_TABLE__RELABELFROM, audit_name, true); /* * check db_xxx:{relabelto} permission */ sepgsql_check_perms(scontext, seclabel, tclass, SEPG_DB_TABLE__RELABELTO, audit_name, true); pfree(tcontext); pfree(audit_name); }
/* * sepgsql_attribute_relabel * * It checks privileges to relabel the supplied column * by the `seclabel'. */ void sepgsql_attribute_relabel(Oid relOid, AttrNumber attnum, const char *seclabel) { char *scontext = sepgsql_get_client_label(); char *tcontext; char *audit_name; ObjectAddress object; if (get_rel_relkind(relOid) != RELKIND_RELATION) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("cannot set security label on non-regular columns"))); object.classId = RelationRelationId; object.objectId = relOid; object.objectSubId = attnum; audit_name = getObjectDescription(&object); /* * check db_column:{setattr relabelfrom} permission */ tcontext = sepgsql_get_label(RelationRelationId, relOid, attnum); sepgsql_check_perms(scontext, tcontext, SEPG_CLASS_DB_COLUMN, SEPG_DB_COLUMN__SETATTR | SEPG_DB_COLUMN__RELABELFROM, audit_name, true); /* * check db_column:{relabelto} permission */ sepgsql_check_perms(scontext, seclabel, SEPG_CLASS_DB_COLUMN, SEPG_DB_PROCEDURE__RELABELTO, audit_name, true); pfree(tcontext); pfree(audit_name); }
/* * sepgsql_attribute_relabel * * It checks privileges to relabel the supplied column * by the `seclabel'. */ void sepgsql_attribute_relabel(Oid relOid, AttrNumber attnum, const char *seclabel) { char *scontext = sepgsql_get_client_label(); char *tcontext; char audit_name[NAMEDATALEN * 2 + 10]; if (get_rel_relkind(relOid) != RELKIND_RELATION) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("cannot set security label on non-regular columns"))); snprintf(audit_name, sizeof(audit_name), "%s.%s", get_rel_name(relOid), get_attname(relOid, attnum)); /* * check db_column:{setattr relabelfrom} permission */ tcontext = sepgsql_get_label(RelationRelationId, relOid, attnum); sepgsql_check_perms(scontext, tcontext, SEPG_CLASS_DB_COLUMN, SEPG_DB_COLUMN__SETATTR | SEPG_DB_COLUMN__RELABELFROM, audit_name, true); pfree(tcontext); /* * check db_column:{relabelto} permission */ sepgsql_check_perms(scontext, seclabel, SEPG_CLASS_DB_COLUMN, SEPG_DB_PROCEDURE__RELABELTO, audit_name, true); }
/* * sepgsql_needs_fmgr_hook * * It informs the core whether the supplied function is trusted procedure, * or not. If true, sepgsql_fmgr_hook shall be invoked at start, end, and * abort time of function invocation. */ static bool sepgsql_needs_fmgr_hook(Oid functionId) { char *old_label; char *new_label; char *function_label; if (next_needs_fmgr_hook && (*next_needs_fmgr_hook)(functionId)) return true; /* * SELinux needs the function to be called via security_definer * wrapper, if this invocation will take a domain-transition. * We call these functions as trusted-procedure, if the security * policy has a rule that switches security label of the client * on execution. */ old_label = sepgsql_get_client_label(); new_label = sepgsql_proc_get_domtrans(functionId); if (strcmp(old_label, new_label) != 0) { pfree(new_label); return true; } pfree(new_label); /* * Even if not a trusted-procedure, this function should not be inlined * unless the client has db_procedure:{execute} permission. * Please note that it shall be actually failed later because of same * reason with ACL_EXECUTE. */ function_label = sepgsql_get_label(ProcedureRelationId, functionId, 0); if (sepgsql_check_perms(sepgsql_get_client_label(), function_label, SEPG_CLASS_DB_PROCEDURE, SEPG_DB_PROCEDURE__EXECUTE, NULL, false) != true) { pfree(function_label); return true; } pfree(function_label); return false; }