Header And Logo

PostgreSQL
| The world's most advanced open source database.

Functions | Variables

selinux.c File Reference

#include "postgres.h"
#include "lib/stringinfo.h"
#include "sepgsql.h"
Include dependency graph for selinux.c:

Go to the source code of this file.

Functions

bool sepgsql_is_enabled (void)
int sepgsql_get_mode (void)
int sepgsql_set_mode (int new_mode)
bool sepgsql_getenforce (void)
void sepgsql_audit_log (bool denied, const char *scontext, const char *tcontext, uint16 tclass, uint32 audited, const char *audit_name)
void sepgsql_compute_avd (const char *scontext, const char *tcontext, uint16 tclass, struct av_decision *avd)
char * sepgsql_compute_create (const char *scontext, const char *tcontext, uint16 tclass, const char *objname)
bool sepgsql_check_perms (const char *scontext, const char *tcontext, uint16 tclass, uint32 required, const char *audit_name, bool abort_on_violation)

Variables

struct {
   const char *   class_name
   uint16   class_code
   struct {
      const char *   av_name
      uint32   av_code
   }   av [32]
selinux_catalog []
static int sepgsql_mode = SEPGSQL_MODE_INTERNAL

Function Documentation

void sepgsql_audit_log ( bool  denied,
const char *  scontext,
const char *  tcontext,
uint16  tclass,
uint32  audited,
const char *  audit_name 
)

Definition at line 677 of file selinux.c.

References appendStringInfo(), Assert, av_name, buf, class_name, StringInfoData::data, ereport, errmsg(), i, initStringInfo(), LOG, selinux_catalog, and SEPG_CLASS_MAX.

Referenced by sepgsql_avc_check_perms_label(), and sepgsql_check_perms().

{
    StringInfoData buf;
    const char *class_name;
    const char *av_name;
    int         i;

    /* lookup name of the object class */
    Assert(tclass < SEPG_CLASS_MAX);
    class_name = selinux_catalog[tclass].class_name;

    /* lookup name of the permissions */
    initStringInfo(&buf);
    appendStringInfo(&buf, "%s {",
                     (denied ? "denied" : "allowed"));
    for (i = 0; selinux_catalog[tclass].av[i].av_name; i++)
    {
        if (audited & (1UL << i))
        {
            av_name = selinux_catalog[tclass].av[i].av_name;
            appendStringInfo(&buf, " %s", av_name);
        }
    }
    appendStringInfo(&buf, " }");

    /*
     * Call external audit module, if loaded
     */
    appendStringInfo(&buf, " scontext=%s tcontext=%s tclass=%s",
                     scontext, tcontext, class_name);
    if (audit_name)
        appendStringInfo(&buf, " name=\"%s\"", audit_name);

    ereport(LOG, (errmsg("SELinux: %s", buf.data)));
}

bool sepgsql_check_perms ( const char *  scontext,
const char *  tcontext,
uint16  tclass,
uint32  required,
const char *  audit_name,
bool  abort_on_violation 
)

Definition at line 902 of file selinux.c.

References ereport, errcode(), errmsg(), ERROR, sepgsql_audit_log(), sepgsql_compute_avd(), sepgsql_get_debug_audit(), sepgsql_getenforce(), sepgsql_mode, and SEPGSQL_MODE_INTERNAL.

{
    struct av_decision avd;
    uint32      denied;
    uint32      audited;
    bool        result = true;

    sepgsql_compute_avd(scontext, tcontext, tclass, &avd);

    denied = required & ~avd.allowed;

    if (sepgsql_get_debug_audit())
        audited = (denied ? denied : required);
    else
        audited = (denied ? (denied & avd.auditdeny)
                   : (required & avd.auditallow));

    if (denied &&
        sepgsql_getenforce() > 0 &&
        (avd.flags & SELINUX_AVD_FLAGS_PERMISSIVE) == 0)
        result = false;

    /*
     * It records a security audit for the request, if needed. But, when
     * SE-PgSQL performs 'internal' mode, it needs to keep silent.
     */
    if (audited && sepgsql_mode != SEPGSQL_MODE_INTERNAL)
    {
        sepgsql_audit_log(denied,
                          scontext,
                          tcontext,
                          tclass,
                          audited,
                          audit_name);
    }

    if (!result && abort_on_violation)
        ereport(ERROR,
                (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
                 errmsg("SELinux: security policy violation")));
    return result;
}

void sepgsql_compute_avd ( const char *  scontext,
const char *  tcontext,
uint16  tclass,
struct av_decision *  avd 
)

Definition at line 732 of file selinux.c.

References Assert, av_code, av_name, class_code, ereport, errcode(), errmsg(), ERROR, i, selinux_catalog, and SEPG_CLASS_MAX.

Referenced by sepgsql_avc_compute(), and sepgsql_check_perms().

{
    const char *tclass_name;
    security_class_t tclass_ex;
    struct av_decision avd_ex;
    int         i,
                deny_unknown = security_deny_unknown();

    /* Get external code of the object class */
    Assert(tclass < SEPG_CLASS_MAX);
    Assert(tclass == selinux_catalog[tclass].class_code);

    tclass_name = selinux_catalog[tclass].class_name;
    tclass_ex = string_to_security_class(tclass_name);

    if (tclass_ex == 0)
    {
        /*
         * If the current security policy does not support permissions
         * corresponding to database objects, we fill up them with dummy data.
         * If security_deny_unknown() returns positive value, undefined
         * permissions should be denied. Otherwise, allowed
         */
        avd->allowed = (security_deny_unknown() > 0 ? 0 : ~0);
        avd->auditallow = 0U;
        avd->auditdeny = ~0U;
        avd->flags = 0;

        return;
    }

    /*
     * Ask SELinux what is allowed set of permissions on a pair of the
     * security contexts and the given object class.
     */
    if (security_compute_av_flags_raw((security_context_t) scontext,
                                      (security_context_t) tcontext,
                                      tclass_ex, 0, &avd_ex) < 0)
        ereport(ERROR,
                (errcode(ERRCODE_INTERNAL_ERROR),
                 errmsg("SELinux could not compute av_decision: "
                        "scontext=%s tcontext=%s tclass=%s: %m",
                        scontext, tcontext, tclass_name)));

    /*
     * SELinux returns its access control decision as a set of permissions
     * represented in external code which depends on run-time environment. So,
     * we need to translate it to the internal representation before returning
     * results for the caller.
     */
    memset(avd, 0, sizeof(struct av_decision));

    for (i = 0; selinux_catalog[tclass].av[i].av_name; i++)
    {
        access_vector_t av_code_ex;
        const char *av_name = selinux_catalog[tclass].av[i].av_name;
        uint32      av_code = selinux_catalog[tclass].av[i].av_code;

        av_code_ex = string_to_av_perm(tclass_ex, av_name);
        if (av_code_ex == 0)
        {
            /* fill up undefined permissions */
            if (!deny_unknown)
                avd->allowed |= av_code;
            avd->auditdeny |= av_code;

            continue;
        }

        if (avd_ex.allowed & av_code_ex)
            avd->allowed |= av_code;
        if (avd_ex.auditallow & av_code_ex)
            avd->auditallow |= av_code;
        if (avd_ex.auditdeny & av_code_ex)
            avd->auditdeny |= av_code;
    }

    return;
}

char* sepgsql_compute_create ( const char *  scontext,
const char *  tcontext,
uint16  tclass,
const char *  objname 
)

Definition at line 837 of file selinux.c.

References Assert, ereport, errcode(), errmsg(), ERROR, PG_CATCH, PG_END_TRY, PG_RE_THROW, PG_TRY, pstrdup(), selinux_catalog, and SEPG_CLASS_MAX.

Referenced by sepgsql_attribute_post_create(), sepgsql_avc_compute(), sepgsql_database_post_create(), sepgsql_proc_post_create(), sepgsql_relation_post_create(), and sepgsql_schema_post_create().

{
    security_context_t ncontext;
    security_class_t tclass_ex;
    const char *tclass_name;
    char       *result;

    /* Get external code of the object class */
    Assert(tclass < SEPG_CLASS_MAX);

    tclass_name = selinux_catalog[tclass].class_name;
    tclass_ex = string_to_security_class(tclass_name);

    /*
     * Ask SELinux what is the default context for the given object class on a
     * pair of security contexts
     */
    if (security_compute_create_name_raw((security_context_t) scontext,
                                         (security_context_t) tcontext,
                                         tclass_ex,
                                         objname,
                                         &ncontext) < 0)
        ereport(ERROR,
                (errcode(ERRCODE_INTERNAL_ERROR),
                 errmsg("SELinux could not compute a new context: "
                        "scontext=%s tcontext=%s tclass=%s: %m",
                        scontext, tcontext, tclass_name)));

    /*
     * libselinux returns malloc()'ed string, so we need to copy it on the
     * palloc()'ed region.
     */
    PG_TRY();
    {
        result = pstrdup(ncontext);
    }
    PG_CATCH();
    {
        freecon(ncontext);
        PG_RE_THROW();
    }
    PG_END_TRY();
    freecon(ncontext);

    return result;
}

int sepgsql_get_mode ( void   ) 

Definition at line 622 of file selinux.c.

References sepgsql_mode.

Referenced by sepgsql_avc_check_perms_label().

{
    return sepgsql_mode;
}

bool sepgsql_getenforce ( void   ) 

Definition at line 648 of file selinux.c.

References sepgsql_mode, and SEPGSQL_MODE_DEFAULT.

Referenced by check_relation_privileges(), sepgsql_avc_check_perms_label(), sepgsql_check_perms(), and sepgsql_utility_command().

{
    if (sepgsql_mode == SEPGSQL_MODE_DEFAULT &&
        selinux_status_getenforce() > 0)
        return true;

    return false;
}

bool sepgsql_is_enabled ( void   ) 

Definition at line 613 of file selinux.c.

References sepgsql_mode, and SEPGSQL_MODE_DISABLED.

Referenced by sepgsql_getcon(), sepgsql_mcstrans_in(), sepgsql_mcstrans_out(), and sepgsql_restorecon().

{
    return (sepgsql_mode != SEPGSQL_MODE_DISABLED ? true : false);
}

int sepgsql_set_mode ( int  new_mode  ) 

Definition at line 631 of file selinux.c.

References sepgsql_mode.

Referenced by _PG_init(), and sepgsql_client_auth().

{
    int         old_mode = sepgsql_mode;

    sepgsql_mode = new_mode;

    return old_mode;
}


Variable Documentation

struct { ... } av[32]

Definition at line 37 of file selinux.c.

Referenced by sepgsql_compute_avd().

const char* av_name

Definition at line 36 of file selinux.c.

Referenced by sepgsql_audit_log(), and sepgsql_compute_avd().

Definition at line 33 of file selinux.c.

Referenced by sepgsql_compute_avd().

const char* class_name

Definition at line 32 of file selinux.c.

Referenced by sepgsql_audit_log().

struct { ... } selinux_catalog[] [static]
int sepgsql_mode = SEPGSQL_MODE_INTERNAL [static]