Ejemplo n.º 1
0
int security_compute_av_raw(const char * scon,
			    const char * tcon,
			    security_class_t tclass,
			    access_vector_t requested,
			    struct av_decision *avd)
{
	struct av_decision lavd;
	int ret;

	ret = security_compute_av_flags_raw(scon, tcon, tclass,
					    requested, &lavd);
	if (ret == 0) {
		avd->allowed = lavd.allowed;
		avd->decided = lavd.decided;
		avd->auditallow = lavd.auditallow;
		avd->auditdeny = lavd.auditdeny;
		avd->seqno = lavd.seqno;
		/* NOTE:
		 * We should not return avd->flags via the interface
		 * due to the binary compatibility.
		 */
	}
	return ret;
}
Ejemplo n.º 2
0
int security_compute_av_flags(const char * scon,
			      const char * tcon,
			      security_class_t tclass,
			      access_vector_t requested,
			      struct av_decision *avd)
{
	char * rscon;
	char * rtcon;
	int ret;

	if (selinux_trans_to_raw_context(scon, &rscon))
		return -1;
	if (selinux_trans_to_raw_context(tcon, &rtcon)) {
		freecon(rscon);
		return -1;
	}
	ret = security_compute_av_flags_raw(rscon, rtcon, tclass,
					    requested, avd);

	freecon(rscon);
	freecon(rtcon);

	return ret;
}
Ejemplo n.º 3
0
/*
 * sepgsql_compute_avd
 *
 * It actually asks SELinux what permissions are allowed on a pair of
 * the security contexts and object class. It also returns what permissions
 * should be audited on access violation or allowed.
 * In most cases, subject's security context (scontext) is a client, and
 * target security context (tcontext) is a database object.
 *
 * The access control decision shall be set on the given av_decision.
 * The av_decision.allowed has a bitmask of SEPG_<class>__<perms>
 * to suggest a set of allowed actions in this object class.
 */
void
sepgsql_compute_avd(const char *scontext,
					const char *tcontext,
					uint16 tclass,
					struct av_decision *avd)
{
	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",
						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;
}