/*
 * Implementation of the userspace access vector cache (AVC).
 *
 * Author : Eamon Walsh <ewalsh@epoch.ncsc.mil>
 *
 * Derived from the kernel AVC implementation by
 * Stephen Smalley <sds@epoch.ncsc.mil> and 
 * James Morris <jmorris@redhat.com>.
 */
#include <selinux/avc.h>
#include "selinux_internal.h"
#include "avc_sidtab.h"
#include "avc_internal.h"

#define AVC_CACHE_SLOTS		512
#define AVC_CACHE_MAXNODES	410

struct avc_entry {
	security_id_t ssid;
	security_id_t tsid;
	security_class_t tclass;
	struct av_decision avd;
	security_id_t	create_sid;
	int used;		/* used recently */
};

struct avc_node {
	struct avc_entry ae;
	struct avc_node *next;
};

struct avc_cache {
	struct avc_node *slots[AVC_CACHE_SLOTS];
	uint32_t lru_hint;	/* LRU hint for reclaim scan */
	uint32_t active_nodes;
	uint32_t latest_notif;	/* latest revocation notification */
};

struct avc_callback_node {
	int (*callback) (uint32_t event, security_id_t ssid,
			 security_id_t tsid,
			 security_class_t tclass, access_vector_t perms,
			 access_vector_t * out_retained);
	uint32_t events;
	security_id_t ssid;
	security_id_t tsid;
	security_class_t tclass;
	access_vector_t perms;
	struct avc_callback_node *next;
};

static void *avc_netlink_thread = NULL;
static void *avc_lock = NULL;
static void *avc_log_lock = NULL;
static struct avc_node *avc_node_freelist = NULL;
static struct avc_cache avc_cache;
static char *avc_audit_buf = NULL;
static struct avc_cache_stats cache_stats;
static struct avc_callback_node *avc_callbacks = NULL;
static struct sidtab avc_sidtab;

static inline int avc_hash(security_id_t ssid,
			   security_id_t tsid, security_class_t tclass)
{
	return ((uintptr_t) ssid ^ ((uintptr_t) tsid << 2) ^ tclass)
	    & (AVC_CACHE_SLOTS - 1);
}

int avc_context_to_sid(const security_context_t ctx, security_id_t * sid)
{
	int rc;
	avc_get_lock(avc_lock);
	rc = sidtab_context_to_sid(&avc_sidtab, ctx, sid);
	avc_release_lock(avc_lock);
	return rc;
}

int avc_sid_to_context(security_id_t sid, security_context_t * ctx)
{
	int rc;
	*ctx = NULL;
	avc_get_lock(avc_lock);
	*ctx = strdup(sid->ctx);	/* caller must free via freecon */
	rc = *ctx ? 0 : -1;
	avc_release_lock(avc_lock);
	return rc;
}

int avc_get_initial_sid(const char * name, security_id_t * sid)
{
	int rc;
	security_context_t con;

	rc = security_get_initial_context(name, &con);
	if (rc < 0)
		return rc;
	rc = avc_context_to_sid(con, sid);

	freecon(con);

	return rc;
}

int avc_open(struct selinux_opt *opts, unsigned nopts)
{
	avc_setenforce = 0;

	while (nopts--)
		switch(opts[nopts].type) {
		case AVC_OPT_SETENFORCE:
			avc_setenforce = 1;
			avc_enforcing = !!opts[nopts].value;
			break;
		}

	return avc_init("avc", NULL, NULL, NULL, NULL);
}

int avc_init(const char *prefix,
	     const struct avc_memory_callback *mem_cb,
	     const struct avc_log_callback *log_cb,
	     const struct avc_thread_callback *thread_cb,
	     const struct avc_lock_callback *lock_cb)
{
	struct avc_node *new;
	int i, rc = 0;

	if (prefix)
		strncpy(avc_prefix, prefix, AVC_PREFIX_SIZE - 1);

	set_callbacks(mem_cb, log_cb, thread_cb, lock_cb);

	avc_lock = avc_alloc_lock();
	avc_log_lock = avc_alloc_lock();

	memset(&cache_stats, 0, sizeof(cache_stats));

	for (i = 0; i < AVC_CACHE_SLOTS; i++)
		avc_cache.slots[i] = 0;
	avc_cache.lru_hint = 0;
	avc_cache.active_nodes = 0;
	avc_cache.latest_notif = 0;

	rc = sidtab_init(&avc_sidtab);
	if (rc) {
		avc_log(SELINUX_ERROR,
			"%s:  unable to initialize SID table\n",
			avc_prefix);
		goto out;
	}

	avc_audit_buf = (char *)avc_malloc(AVC_AUDIT_BUFSIZE);
	if (!avc_audit_buf) {
		avc_log(SELINUX_ERROR,
			"%s:  unable to allocate audit buffer\n",
			avc_prefix);
		rc = -1;
		goto out;
	}

	for (i = 0; i < AVC_CACHE_MAXNODES; i++) {
		new = avc_malloc(sizeof(*new));
		if (!new) {
			avc_log(SELINUX_WARNING,
				"%s:  warning: only got %d av entries\n",
				avc_prefix, i);
			break;
		}
		memset(new, 0, sizeof(*new));
		new->next = avc_node_freelist;
		avc_node_freelist = new;
	}

	if (!avc_setenforce) {
		rc = security_getenforce();
		if (rc < 0) {
			avc_log(SELINUX_ERROR,
				"%s:  could not determine enforcing mode: %s\n",
				avc_prefix,
				strerror(errno));
			goto out;
		}
		avc_enforcing = rc;
	}

	rc = avc_netlink_open(0);
	if (rc < 0) {
		avc_log(SELINUX_ERROR,
			"%s:  can't open netlink socket: %d (%s)\n",
			avc_prefix, errno, strerror(errno));
		goto out;
	}
	if (avc_using_threads) {
		avc_netlink_thread = avc_create_thread(&avc_netlink_loop);
		avc_netlink_trouble = 0;
	}
	avc_running = 1;
      out:
	return rc;
}

void avc_cache_stats(struct avc_cache_stats *p)
{
	memcpy(p, &cache_stats, sizeof(cache_stats));
}

void avc_sid_stats(void)
{
	avc_get_lock(avc_log_lock);
	avc_get_lock(avc_lock);
	sidtab_sid_stats(&avc_sidtab, avc_audit_buf, AVC_AUDIT_BUFSIZE);
	avc_release_lock(avc_lock);
	avc_log(SELINUX_INFO, "%s", avc_audit_buf);
	avc_release_lock(avc_log_lock);
}

void avc_av_stats(void)
{
	int i, chain_len, max_chain_len, slots_used;
	struct avc_node *node;

	avc_get_lock(avc_lock);

	slots_used = 0;
	max_chain_len = 0;
	for (i = 0; i < AVC_CACHE_SLOTS; i++) {
		node = avc_cache.slots[i];
		if (node) {
			slots_used++;
			chain_len = 0;
			while (node) {
				chain_len++;
				node = node->next;
			}
			if (chain_len > max_chain_len)
				max_chain_len = chain_len;
		}
	}

	avc_release_lock(avc_lock);

	avc_log(SELINUX_INFO, "%s:  %d AV entries and %d/%d buckets used, "
		"longest chain length %d\n", avc_prefix,
		avc_cache.active_nodes,
		slots_used, AVC_CACHE_SLOTS, max_chain_len);
}

hidden_def(avc_av_stats)

static inline struct avc_node *avc_reclaim_node(void)
{
	struct avc_node *prev, *cur;
	int try;
	uint32_t hvalue;

	hvalue = avc_cache.lru_hint;
	for (try = 0; try < 2; try++) {
		do {
			prev = NULL;
			cur = avc_cache.slots[hvalue];
			while (cur) {
				if (!cur->ae.used)
					goto found;

				cur->ae.used = 0;

				prev = cur;
				cur = cur->next;
			}
			hvalue = (hvalue + 1) & (AVC_CACHE_SLOTS - 1);
		} while (hvalue != avc_cache.lru_hint);
	}

	errno = ENOMEM;		/* this was a panic in the kernel... */
	return NULL;

      found:
	avc_cache.lru_hint = hvalue;

	if (prev == NULL)
		avc_cache.slots[hvalue] = cur->next;
	else
		prev->next = cur->next;

	return cur;
}

static inline void avc_clear_avc_entry(struct avc_entry *ae)
{
	ae->ssid = ae->tsid = ae->create_sid = NULL;
	ae->tclass = 0;
	ae->avd.allowed = ae->avd.decided = 0;
	ae->avd.auditallow = ae->avd.auditdeny = 0;
	ae->used = 0;
}

static inline struct avc_node *avc_claim_node(security_id_t ssid,
					      security_id_t tsid,
					      security_class_t tclass)
{
	struct avc_node *new;
	int hvalue;

	if (!avc_node_freelist)
		avc_cleanup();

	if (avc_node_freelist) {
		new = avc_node_freelist;
		avc_node_freelist = avc_node_freelist->next;
		avc_cache.active_nodes++;
	} else {
		new = avc_reclaim_node();
		if (!new)
			goto out;
	}

	hvalue = avc_hash(ssid, tsid, tclass);
	avc_clear_avc_entry(&new->ae);
	new->ae.used = 1;
	new->ae.ssid = ssid;
	new->ae.tsid = tsid;
	new->ae.tclass = tclass;
	new->next = avc_cache.slots[hvalue];
	avc_cache.slots[hvalue] = new;

      out:
	return new;
}

static inline struct avc_node *avc_search_node(security_id_t ssid,
					       security_id_t tsid,
					       security_class_t tclass,
					       int *probes)
{
	struct avc_node *cur;
	int hvalue;
	int tprobes = 1;

	hvalue = avc_hash(ssid, tsid, tclass);
	cur = avc_cache.slots[hvalue];
	while (cur != NULL &&
	       (ssid != cur->ae.ssid ||
		tclass != cur->ae.tclass || tsid != cur->ae.tsid)) {
		tprobes++;
		cur = cur->next;
	}

	if (cur == NULL) {
		/* cache miss */
		goto out;
	}

	/* cache hit */
	if (probes)
		*probes = tprobes;

	cur->ae.used = 1;

      out:
	return cur;
}

/**
 * avc_lookup - Look up an AVC entry.
 * @ssid: source security identifier
 * @tsid: target security identifier
 * @tclass: target security class
 * @requested: requested permissions, interpreted based on @tclass
 * @aeref:  AVC entry reference
 *
 * Look up an AVC entry that is valid for the
 * @requested permissions between the SID pair
 * (@ssid, @tsid), interpreting the permissions
 * based on @tclass.  If a valid AVC entry exists,
 * then this function updates @aeref to refer to the
 * entry and returns %0.  Otherwise, -1 is returned.
 */
static int avc_lookup(security_id_t ssid, security_id_t tsid,
		      security_class_t tclass,
		      access_vector_t requested, struct avc_entry_ref *aeref)
{
	struct avc_node *node;
	int probes, rc = 0;

	avc_cache_stats_incr(cav_lookups);
	node = avc_search_node(ssid, tsid, tclass, &probes);

	if (node && ((node->ae.avd.decided & requested) == requested)) {
		avc_cache_stats_incr(cav_hits);
		avc_cache_stats_add(cav_probes, probes);
		aeref->ae = &node->ae;
		goto out;
	}

	avc_cache_stats_incr(cav_misses);
	rc = -1;
      out:
	return rc;
}

/**
 * avc_insert - Insert an AVC entry.
 * @ssid: source security identifier
 * @tsid: target security identifier
 * @tclass: target security class
 * @ae: AVC entry
 * @aeref:  AVC entry reference
 *
 * Insert an AVC entry for the SID pair
 * (@ssid, @tsid) and class @tclass.
 * The access vectors and the sequence number are
 * normally provided by the security server in
 * response to a security_compute_av() call.  If the
 * sequence number @ae->avd.seqno is not less than the latest
 * revocation notification, then the function copies
 * the access vectors into a cache entry, updates
 * @aeref to refer to the entry, and returns %0.
 * Otherwise, this function returns -%1 with @errno set to %EAGAIN.
 */
static int avc_insert(security_id_t ssid, security_id_t tsid,
		      security_class_t tclass,
		      struct avc_entry *ae, struct avc_entry_ref *aeref)
{
	struct avc_node *node;
	int rc = 0;

	if (ae->avd.seqno < avc_cache.latest_notif) {
		avc_log(SELINUX_WARNING,
			"%s:  seqno %d < latest_notif %d\n", avc_prefix,
			ae->avd.seqno, avc_cache.latest_notif);
		errno = EAGAIN;
		rc = -1;
		goto out;
	}

	node = avc_claim_node(ssid, tsid, tclass);
	if (!node) {
		rc = -1;
		goto out;
	}

	node->ae.avd.allowed = ae->avd.allowed;
	node->ae.avd.decided = ae->avd.decided;
	node->ae.avd.auditallow = ae->avd.auditallow;
	node->ae.avd.auditdeny = ae->avd.auditdeny;
	node->ae.avd.seqno = ae->avd.seqno;
	aeref->ae = &node->ae;
      out:
	return rc;
}

void avc_cleanup(void)
{
}

hidden_def(avc_cleanup)

int avc_reset(void)
{
	struct avc_callback_node *c;
	int i, ret, rc = 0, errsave = 0;
	struct avc_node *node, *tmp;
	errno = 0;

	if (!avc_running)
		return 0;

	avc_get_lock(avc_lock);

	for (i = 0; i < AVC_CACHE_SLOTS; i++) {
		node = avc_cache.slots[i];
		while (node) {
			tmp = node;
			node = node->next;
			avc_clear_avc_entry(&tmp->ae);
			tmp->next = avc_node_freelist;
			avc_node_freelist = tmp;
			avc_cache.active_nodes--;
		}
		avc_cache.slots[i] = 0;
	}
	avc_cache.lru_hint = 0;

	avc_release_lock(avc_lock);

	memset(&cache_stats, 0, sizeof(cache_stats));

	for (c = avc_callbacks; c; c = c->next) {
		if (c->events & AVC_CALLBACK_RESET) {
			ret = c->callback(AVC_CALLBACK_RESET, 0, 0, 0, 0, 0);
			if (ret && !rc) {
				rc = ret;
				errsave = errno;
			}
		}
	}
	errno = errsave;
	return rc;
}

hidden_def(avc_reset)

void avc_destroy(void)
{
	struct avc_callback_node *c;
	struct avc_node *node, *tmp;
	int i;

	avc_get_lock(avc_lock);

	if (avc_using_threads)
		avc_stop_thread(avc_netlink_thread);
	avc_netlink_close();

	for (i = 0; i < AVC_CACHE_SLOTS; i++) {
		node = avc_cache.slots[i];
		while (node) {
			tmp = node;
			node = node->next;
			avc_free(tmp);
		}
	}
	while (avc_node_freelist) {
		tmp = avc_node_freelist;
		avc_node_freelist = tmp->next;
		avc_free(tmp);
	}
	avc_release_lock(avc_lock);

	while (avc_callbacks) {
		c = avc_callbacks;
		avc_callbacks = c->next;
		avc_free(c);
	}
	sidtab_destroy(&avc_sidtab);
	avc_free_lock(avc_lock);
	avc_free_lock(avc_log_lock);
	avc_free(avc_audit_buf);
	avc_running = 0;
}

/* ratelimit stuff put aside for now --EFW */
#if 0
/*
 * Copied from net/core/utils.c:net_ratelimit and modified for
 * use by the AVC audit facility.
 */
#define AVC_MSG_COST	5*HZ
#define AVC_MSG_BURST	10*5*HZ

/*
 * This enforces a rate limit: not more than one kernel message
 * every 5secs to make a denial-of-service attack impossible.
 */
static int avc_ratelimit(void)
{
	static unsigned long toks = 10 * 5 * HZ;
	static unsigned long last_msg;
	static int missed, rc = 0;
	unsigned long now = jiffies;
	void *ratelimit_lock = avc_alloc_lock();

	avc_get_lock(ratelimit_lock);
	toks += now - last_msg;
	last_msg = now;
	if (toks > AVC_MSG_BURST)
		toks = AVC_MSG_BURST;
	if (toks >= AVC_MSG_COST) {
		int lost = missed;
		missed = 0;
		toks -= AVC_MSG_COST;
		avc_release_lock(ratelimit_lock);
		if (lost) {
			avc_log(SELINUX_WARNING,
				"%s:  %d messages suppressed.\n", avc_prefix,
				lost);
		}
		rc = 1;
		goto out;
	}
	missed++;
	avc_release_lock(ratelimit_lock);
      out:
	avc_free_lock(ratelimit_lock);
	return rc;
}

static inline int check_avc_ratelimit(void)
{
	if (avc_enforcing)
		return avc_ratelimit();
	else {
		/* If permissive, then never suppress messages. */
		return 1;
	}
}
#endif				/* ratelimit stuff */

/**
 * avc_dump_av - Display an access vector in human-readable form.
 * @tclass: target security class
 * @av: access vector
 */
static void avc_dump_av(security_class_t tclass, access_vector_t av)
{
	const char *permstr;
	access_vector_t bit = 1;

	if (av == 0) {
		log_append(avc_audit_buf, " null");
		return;
	}

	log_append(avc_audit_buf, " {");

	while (av) {
		if (av & bit) {
			permstr = security_av_perm_to_string(tclass, bit);
			if (!permstr)
				break;
			log_append(avc_audit_buf, " %s", permstr);
			av &= ~bit;
		}
		bit <<= 1;
	}

	if (av)
		log_append(avc_audit_buf, " 0x%x", av);
	log_append(avc_audit_buf, " }");
}

/**
 * avc_dump_query - Display a SID pair and a class in human-readable form.
 * @ssid: source security identifier
 * @tsid: target security identifier
 * @tclass: target security class
 */
static void avc_dump_query(security_id_t ssid, security_id_t tsid,
			   security_class_t tclass)
{
	avc_get_lock(avc_lock);

	log_append(avc_audit_buf, "scontext=%s tcontext=%s",
		   ssid->ctx, tsid->ctx);

	avc_release_lock(avc_lock);
	log_append(avc_audit_buf, " tclass=%s",
		   security_class_to_string(tclass));
}

void avc_audit(security_id_t ssid, security_id_t tsid,
	       security_class_t tclass, access_vector_t requested,
	       struct av_decision *avd, int result, void *a)
{
	access_vector_t denied, audited;

	denied = requested & ~avd->allowed;
	if (denied)
		audited = denied & avd->auditdeny;
	else if (!requested || result)
		audited = denied = requested;
	else
		audited = requested & avd->auditallow;
	if (!audited)
		return;
#if 0
	if (!check_avc_ratelimit())
		return;
#endif
	/* prevent overlapping buffer writes */
	avc_get_lock(avc_log_lock);
	snprintf(avc_audit_buf, AVC_AUDIT_BUFSIZE,
		 "%s:  %s ", avc_prefix, (denied || !requested) ? "denied" : "granted");
	avc_dump_av(tclass, audited);
	log_append(avc_audit_buf, " for ");

	/* get any extra information printed by the callback */
	avc_suppl_audit(a, tclass, avc_audit_buf + strlen(avc_audit_buf),
			AVC_AUDIT_BUFSIZE - strlen(avc_audit_buf));

	log_append(avc_audit_buf, " ");
	avc_dump_query(ssid, tsid, tclass);
	log_append(avc_audit_buf, "\n");
	avc_log(SELINUX_AVC, "%s", avc_audit_buf);

	avc_release_lock(avc_log_lock);
}

hidden_def(avc_audit)

int avc_has_perm_noaudit(security_id_t ssid,
			 security_id_t tsid,
			 security_class_t tclass,
			 access_vector_t requested,
			 struct avc_entry_ref *aeref, struct av_decision *avd)
{
	struct avc_entry *ae;
	int rc = 0;
	struct avc_entry entry;
	access_vector_t denied;
	struct avc_entry_ref ref;

	if (!avc_using_threads && !avc_app_main_loop) {
		(void)avc_netlink_check_nb();
	}

	if (!aeref) {
		avc_entry_ref_init(&ref);
		aeref = &ref;
	}

	avc_get_lock(avc_lock);
	avc_cache_stats_incr(entry_lookups);
	ae = aeref->ae;
	if (ae) {
		if (ae->ssid == ssid &&
		    ae->tsid == tsid &&
		    ae->tclass == tclass &&
		    ((ae->avd.decided & requested) == requested)) {
			avc_cache_stats_incr(entry_hits);
			ae->used = 1;
		} else {
			avc_cache_stats_incr(entry_discards);
			ae = 0;
		}
	}

	if (!ae) {
		avc_cache_stats_incr(entry_misses);
		rc = avc_lookup(ssid, tsid, tclass, requested, aeref);
		if (rc) {
			rc = security_compute_av(ssid->ctx, tsid->ctx,
						 tclass, requested,
						 &entry.avd);
			if (rc)
				goto out;
			rc = avc_insert(ssid, tsid, tclass, &entry, aeref);
			if (rc)
				goto out;
		}
		ae = aeref->ae;
	}

	if (avd)
		memcpy(avd, &ae->avd, sizeof(*avd));

	denied = requested & ~(ae->avd.allowed);

	if (!requested || denied) {
		if (!avc_enforcing ||
		    (ae->avd.flags & SELINUX_AVD_FLAGS_PERMISSIVE))
			ae->avd.allowed |= requested;
		else {
			errno = EACCES;
			rc = -1;
		}
	}

      out:
	avc_release_lock(avc_lock);
	return rc;
}

hidden_def(avc_has_perm_noaudit)

int avc_has_perm(security_id_t ssid, security_id_t tsid,
		 security_class_t tclass, access_vector_t requested,
		 struct avc_entry_ref *aeref, void *auditdata)
{
	struct av_decision avd;
	int errsave, rc;

	memset(&avd, 0, sizeof(avd));

	rc = avc_has_perm_noaudit(ssid, tsid, tclass, requested, aeref, &avd);
	errsave = errno;
	avc_audit(ssid, tsid, tclass, requested, &avd, rc, auditdata);
	errno = errsave;
	return rc;
}

int avc_compute_create(security_id_t ssid,  security_id_t tsid,
		       security_class_t tclass, security_id_t *newsid)
{
	int rc;
	struct avc_entry_ref aeref;
	struct avc_entry entry;
	security_context_t ctx;

	*newsid = NULL;
	avc_entry_ref_init(&aeref);

	avc_get_lock(avc_lock);

	/* check for a cached entry */
	rc = avc_lookup(ssid, tsid, tclass, 0, &aeref);
	if (rc) {
		/* need to make a cache entry for this tuple */
		rc = security_compute_av(ssid->ctx, tsid->ctx,
					 tclass, 0, &entry.avd);
		if (rc)
			goto out;
		rc = avc_insert(ssid, tsid, tclass, &entry, &aeref);
		if (rc)
			goto out;
	}

	/* check for a saved compute_create value */
	if (!aeref.ae->create_sid) {
		/* need to query the kernel policy */
		rc = security_compute_create(ssid->ctx, tsid->ctx, tclass,
						 &ctx);
		if (rc)
			goto out;
		rc = sidtab_context_to_sid(&avc_sidtab, ctx, newsid);
		freecon(ctx);
		if (rc)
			goto out;

		aeref.ae->create_sid = *newsid;
	} else {
		/* found saved value */
		*newsid = aeref.ae->create_sid;
	}

	rc = 0;
out:
	avc_release_lock(avc_lock);
	return rc;
}

int avc_add_callback(int (*callback) (uint32_t event, security_id_t ssid,
				      security_id_t tsid,
				      security_class_t tclass,
				      access_vector_t perms,
				      access_vector_t * out_retained),
		     uint32_t events, security_id_t ssid,
		     security_id_t tsid,
		     security_class_t tclass, access_vector_t perms)
{
	struct avc_callback_node *c;
	int rc = 0;

	c = avc_malloc(sizeof(*c));
	if (!c) {
		rc = -1;
		goto out;
	}

	c->callback = callback;
	c->events = events;
	c->ssid = ssid;
	c->tsid = tsid;
	c->tclass = tclass;
	c->perms = perms;
	c->next = avc_callbacks;
	avc_callbacks = c;
      out:
	return rc;
}

static inline int avc_sidcmp(security_id_t x, security_id_t y)
{
	return (x == y || x == SECSID_WILD || y == SECSID_WILD);
}

static inline void avc_update_node(uint32_t event, struct avc_node *node,
				   access_vector_t perms)
{
	switch (event) {
	case AVC_CALLBACK_GRANT:
		node->ae.avd.allowed |= perms;
		break;
	case AVC_CALLBACK_TRY_REVOKE:
	case AVC_CALLBACK_REVOKE:
		node->ae.avd.allowed &= ~perms;
		break;
	case AVC_CALLBACK_AUDITALLOW_ENABLE:
		node->ae.avd.auditallow |= perms;
		break;
	case AVC_CALLBACK_AUDITALLOW_DISABLE:
		node->ae.avd.auditallow &= ~perms;
		break;
	case AVC_CALLBACK_AUDITDENY_ENABLE:
		node->ae.avd.auditdeny |= perms;
		break;
	case AVC_CALLBACK_AUDITDENY_DISABLE:
		node->ae.avd.auditdeny &= ~perms;
		break;
	}
}

static int avc_update_cache(uint32_t event, security_id_t ssid,
			    security_id_t tsid, security_class_t tclass,
			    access_vector_t perms)
{
	struct avc_node *node;
	int i;

	avc_get_lock(avc_lock);

	if (ssid == SECSID_WILD || tsid == SECSID_WILD) {
		/* apply to all matching nodes */
		for (i = 0; i < AVC_CACHE_SLOTS; i++) {
			for (node = avc_cache.slots[i]; node; node = node->next) {
				if (avc_sidcmp(ssid, node->ae.ssid) &&
				    avc_sidcmp(tsid, node->ae.tsid) &&
				    tclass == node->ae.tclass) {
					avc_update_node(event, node, perms);
				}
			}
		}
	} else {
		/* apply to one node */
		node = avc_search_node(ssid, tsid, tclass, 0);
		if (node) {
			avc_update_node(event, node, perms);
		}
	}

	avc_release_lock(avc_lock);

	return 0;
}

/* avc_control - update cache and call callbacks
 *
 * This should not be called directly; use the individual event
 * functions instead.
 */
static int avc_control(uint32_t event, security_id_t ssid,
		       security_id_t tsid, security_class_t tclass,
		       access_vector_t perms,
		       uint32_t seqno, access_vector_t * out_retained)
{
	struct avc_callback_node *c;
	access_vector_t tretained = 0, cretained = 0;
	int ret, rc = 0, errsave = 0;
	errno = 0;

	/*
	 * try_revoke only removes permissions from the cache
	 * state if they are not retained by the object manager.
	 * Hence, try_revoke must wait until after the callbacks have
	 * been invoked to update the cache state.
	 */
	if (event != AVC_CALLBACK_TRY_REVOKE)
		avc_update_cache(event, ssid, tsid, tclass, perms);

	for (c = avc_callbacks; c; c = c->next) {
		if ((c->events & event) &&
		    avc_sidcmp(c->ssid, ssid) &&
		    avc_sidcmp(c->tsid, tsid) &&
		    c->tclass == tclass && (c->perms & perms)) {
			cretained = 0;
			ret = c->callback(event, ssid, tsid, tclass,
					  (c->perms & perms), &cretained);
			if (ret && !rc) {
				rc = ret;
				errsave = errno;
			}
			if (!ret)
				tretained |= cretained;
		}
	}

	if (event == AVC_CALLBACK_TRY_REVOKE) {
		/* revoke any unretained permissions */
		perms &= ~tretained;
		avc_update_cache(event, ssid, tsid, tclass, perms);
		*out_retained = tretained;
	}

	avc_get_lock(avc_lock);
	if (seqno > avc_cache.latest_notif)
		avc_cache.latest_notif = seqno;
	avc_release_lock(avc_lock);

	errno = errsave;
	return rc;
}

/**
 * avc_ss_grant - Grant previously denied permissions.
 * @ssid: source security identifier or %SECSID_WILD
 * @tsid: target security identifier or %SECSID_WILD
 * @tclass: target security class
 * @perms: permissions to grant
 * @seqno: policy sequence number
 */
int avc_ss_grant(security_id_t ssid, security_id_t tsid,
		 security_class_t tclass, access_vector_t perms,
		 uint32_t seqno)
{
	return avc_control(AVC_CALLBACK_GRANT,
			   ssid, tsid, tclass, perms, seqno, 0);
}

/**
 * avc_ss_try_revoke - Try to revoke previously granted permissions.
 * @ssid: source security identifier or %SECSID_WILD
 * @tsid: target security identifier or %SECSID_WILD
 * @tclass: target security class
 * @perms: permissions to grant
 * @seqno: policy sequence number
 * @out_retained: subset of @perms that are retained
 *
 * Try to revoke previously granted permissions, but
 * only if they are not retained as migrated permissions.
 * Return the subset of permissions that are retained via @out_retained.
 */
int avc_ss_try_revoke(security_id_t ssid, security_id_t tsid,
		      security_class_t tclass,
		      access_vector_t perms, uint32_t seqno,
		      access_vector_t * out_retained)
{
	return avc_control(AVC_CALLBACK_TRY_REVOKE,
			   ssid, tsid, tclass, perms, seqno, out_retained);
}

/**
 * avc_ss_revoke - Revoke previously granted permissions.
 * @ssid: source security identifier or %SECSID_WILD
 * @tsid: target security identifier or %SECSID_WILD
 * @tclass: target security class
 * @perms: permissions to grant
 * @seqno: policy sequence number
 *
 * Revoke previously granted permissions, even if
 * they are retained as migrated permissions.
 */
int avc_ss_revoke(security_id_t ssid, security_id_t tsid,
		  security_class_t tclass, access_vector_t perms,
		  uint32_t seqno)
{
	return avc_control(AVC_CALLBACK_REVOKE,
			   ssid, tsid, tclass, perms, seqno, 0);
}

/**
 * avc_ss_reset - Flush the cache and revalidate migrated permissions.
 * @seqno: policy sequence number
 */
int avc_ss_reset(uint32_t seqno)
{
	int rc;

	rc = avc_reset();

	avc_get_lock(avc_lock);
	if (seqno > avc_cache.latest_notif)
		avc_cache.latest_notif = seqno;
	avc_release_lock(avc_lock);

	return rc;
}

/**
 * avc_ss_set_auditallow - Enable or disable auditing of granted permissions.
 * @ssid: source security identifier or %SECSID_WILD
 * @tsid: target security identifier or %SECSID_WILD
 * @tclass: target security class
 * @perms: permissions to grant
 * @seqno: policy sequence number
 * @enable: enable flag.
 */
int avc_ss_set_auditallow(security_id_t ssid, security_id_t tsid,
			  security_class_t tclass, access_vector_t perms,
			  uint32_t seqno, uint32_t enable)
{
	if (enable)
		return avc_control(AVC_CALLBACK_AUDITALLOW_ENABLE,
				   ssid, tsid, tclass, perms, seqno, 0);
	else
		return avc_control(AVC_CALLBACK_AUDITALLOW_DISABLE,
				   ssid, tsid, tclass, perms, seqno, 0);
}

/**
 * avc_ss_set_auditdeny - Enable or disable auditing of denied permissions.
 * @ssid: source security identifier or %SECSID_WILD
 * @tsid: target security identifier or %SECSID_WILD
 * @tclass: target security class
 * @perms: permissions to grant
 * @seqno: policy sequence number
 * @enable: enable flag.
 */
int avc_ss_set_auditdeny(security_id_t ssid, security_id_t tsid,
			 security_class_t tclass, access_vector_t perms,
			 uint32_t seqno, uint32_t enable)
{
	if (enable)
		return avc_control(AVC_CALLBACK_AUDITDENY_ENABLE,
				   ssid, tsid, tclass, perms, seqno, 0);
	else
		return avc_control(AVC_CALLBACK_AUDITDENY_DISABLE,
				   ssid, tsid, tclass, perms, seqno, 0);
}
