/*
 * Implementation of the userspace SID hashtable.
 *
 * Author : Eamon Walsh, <ewalsh@epoch.ncsc.mil>
 */
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "selinux_internal.h"
#include <selinux/avc.h>
#include "avc_sidtab.h"
#include "avc_internal.h"

static inline unsigned sidtab_hash(const char * key)
{
	const char *p;
	unsigned int size;
	unsigned int val;

	val = 0;
	size = strlen(key);
	for (p = key; (unsigned int)(p - key) < size; p++)
		val =
		    (val << 4 | (val >> (8 * sizeof(unsigned int) - 4))) ^ (*p);
	return val & (SIDTAB_SIZE - 1);
}

int sidtab_init(struct sidtab *s)
{
	int i, rc = 0;

	s->htable = (struct sidtab_node **)avc_malloc
	    (sizeof(struct sidtab_node *) * SIDTAB_SIZE);

	if (!s->htable) {
		rc = -1;
		goto out;
	}
	for (i = 0; i < SIDTAB_SIZE; i++)
		s->htable[i] = NULL;
	s->nel = 0;
      out:
	return rc;
}

int sidtab_insert(struct sidtab *s, const char * ctx)
{
	int hvalue, rc = 0;
	struct sidtab_node *newnode;
	char * newctx;

	newnode = (struct sidtab_node *)avc_malloc(sizeof(*newnode));
	if (!newnode) {
		rc = -1;
		goto out;
	}
	newctx = strdup(ctx);
	if (!newctx) {
		rc = -1;
		avc_free(newnode);
		goto out;
	}

	hvalue = sidtab_hash(newctx);
	newnode->next = s->htable[hvalue];
	newnode->sid_s.ctx = newctx;
	newnode->sid_s.refcnt = 1;	/* unused */
	s->htable[hvalue] = newnode;
	s->nel++;
      out:
	return rc;
}

int
sidtab_context_to_sid(struct sidtab *s,
		      const char * ctx, security_id_t * sid)
{
	int hvalue, rc = 0;
	struct sidtab_node *cur;

	*sid = NULL;
	hvalue = sidtab_hash(ctx);

      loop:
	cur = s->htable[hvalue];
	while (cur != NULL && strcmp(cur->sid_s.ctx, ctx))
		cur = cur->next;

	if (cur == NULL) {	/* need to make a new entry */
		rc = sidtab_insert(s, ctx);
		if (rc)
			goto out;
		goto loop;	/* find the newly inserted node */
	}

	*sid = &cur->sid_s;
      out:
	return rc;
}

void sidtab_sid_stats(struct sidtab *s, char *buf, int buflen)
{
	int i, chain_len, slots_used, max_chain_len;
	struct sidtab_node *cur;

	slots_used = 0;
	max_chain_len = 0;
	for (i = 0; i < SIDTAB_SIZE; i++) {
		cur = s->htable[i];
		if (cur) {
			slots_used++;
			chain_len = 0;
			while (cur) {
				chain_len++;
				cur = cur->next;
			}

			if (chain_len > max_chain_len)
				max_chain_len = chain_len;
		}
	}

	snprintf(buf, buflen,
		 "%s:  %u SID entries and %d/%d buckets used, longest "
		 "chain length %d\n", avc_prefix, s->nel, slots_used,
		 SIDTAB_SIZE, max_chain_len);
}

void sidtab_destroy(struct sidtab *s)
{
	int i;
	struct sidtab_node *cur, *temp;

	if (!s)
		return;

	for (i = 0; i < SIDTAB_SIZE; i++) {
		cur = s->htable[i];
		while (cur != NULL) {
			temp = cur;
			cur = cur->next;
			freecon(temp->sid_s.ctx);
			avc_free(temp);
		}
		s->htable[i] = NULL;
	}
	avc_free(s->htable);
	s->htable = NULL;
}
