/*
 * Copyright (c) 2007 Pawel Jakub Dawidek <pjd@FreeBSD.org>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");

#include <sys/types.h>
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/proc.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/sx.h>
#include <sys/malloc.h>
#include <sys/queue.h>
#include <sys/jail.h>
#include <sys/osd.h>
#include <sys/priv.h>
#include <sys/zone.h>

#include <sys/policy.h>

static MALLOC_DEFINE(M_ZONES, "zones_data", "Zones data");

/*
 * Structure to record list of ZFS datasets exported to a zone.
 */
typedef struct zone_dataset {
	LIST_ENTRY(zone_dataset) zd_next;
	char	zd_dataset[0];
} zone_dataset_t;

LIST_HEAD(zone_dataset_head, zone_dataset);

static int zone_slot;

int
zone_dataset_attach(struct ucred *cred, const char *dataset, int jailid)
{
	struct zone_dataset_head *head;
	zone_dataset_t *zd, *zd2;
	struct prison *pr;
	int dofree, error;

	if ((error = spl_priv_check_cred(cred, PRIV_ZFS_JAIL)) != 0)
		return (error);

	/* Allocate memory before we grab prison's mutex. */
	zd = malloc(sizeof (*zd) + strlen(dataset) + 1, M_ZONES, M_WAITOK);

	sx_slock(&allprison_lock);
	pr = prison_find(jailid);	/* Locks &pr->pr_mtx. */
	sx_sunlock(&allprison_lock);
	if (pr == NULL) {
		free(zd, M_ZONES);
		return (ENOENT);
	}

	head = osd_jail_get(pr, zone_slot);
	if (head != NULL) {
		dofree = 0;
		LIST_FOREACH(zd2, head, zd_next) {
			if (strcmp(dataset, zd2->zd_dataset) == 0) {
				free(zd, M_ZONES);
				error = EEXIST;
				goto end;
			}
		}
	} else {
		dofree = 1;
		prison_hold_locked(pr);
		mtx_unlock(&pr->pr_mtx);
		head = malloc(sizeof (*head), M_ZONES, M_WAITOK);
		LIST_INIT(head);
		mtx_lock(&pr->pr_mtx);
		error = osd_jail_set(pr, zone_slot, head);
		KASSERT(error == 0, ("osd_jail_set() failed (error=%d)",
		    error));
	}
	strcpy(zd->zd_dataset, dataset);
	LIST_INSERT_HEAD(head, zd, zd_next);
end:
	if (dofree)
		prison_free_locked(pr);
	else
		mtx_unlock(&pr->pr_mtx);
	return (error);
}

int
zone_dataset_detach(struct ucred *cred, const char *dataset, int jailid)
{
	struct zone_dataset_head *head;
	zone_dataset_t *zd;
	struct prison *pr;
	int error;

	if ((error = spl_priv_check_cred(cred, PRIV_ZFS_JAIL)) != 0)
		return (error);

	sx_slock(&allprison_lock);
	pr = prison_find(jailid);
	sx_sunlock(&allprison_lock);
	if (pr == NULL)
		return (ENOENT);
	head = osd_jail_get(pr, zone_slot);
	if (head == NULL) {
		error = ENOENT;
		goto end;
	}
	LIST_FOREACH(zd, head, zd_next) {
		if (strcmp(dataset, zd->zd_dataset) == 0)
			break;
	}
	if (zd == NULL)
		error = ENOENT;
	else {
		LIST_REMOVE(zd, zd_next);
		free(zd, M_ZONES);
		if (LIST_EMPTY(head))
			osd_jail_del(pr, zone_slot);
		error = 0;
	}
end:
	mtx_unlock(&pr->pr_mtx);
	return (error);
}

/*
 * Returns true if the named dataset is visible in the current zone.
 * The 'write' parameter is set to 1 if the dataset is also writable.
 */
int
zone_dataset_visible(const char *dataset, int *write)
{
	struct zone_dataset_head *head;
	zone_dataset_t *zd;
	struct prison *pr;
	size_t len;
	int ret = 0;

	if (dataset[0] == '\0')
		return (0);
	if (INGLOBALZONE(curproc)) {
		if (write != NULL)
			*write = 1;
		return (1);
	}
	pr = curthread->td_ucred->cr_prison;
	mtx_lock(&pr->pr_mtx);
	head = osd_jail_get(pr, zone_slot);
	if (head == NULL)
		goto end;

	/*
	 * Walk the list once, looking for datasets which match exactly, or
	 * specify a dataset underneath an exported dataset.  If found, return
	 * true and note that it is writable.
	 */
	LIST_FOREACH(zd, head, zd_next) {
		len = strlen(zd->zd_dataset);
		if (strlen(dataset) >= len &&
		    bcmp(dataset, zd->zd_dataset, len) == 0 &&
		    (dataset[len] == '\0' || dataset[len] == '/' ||
		    dataset[len] == '@')) {
			if (write)
				*write = 1;
			ret = 1;
			goto end;
		}
	}

	/*
	 * Walk the list a second time, searching for datasets which are parents
	 * of exported datasets.  These should be visible, but read-only.
	 *
	 * Note that we also have to support forms such as 'pool/dataset/', with
	 * a trailing slash.
	 */
	LIST_FOREACH(zd, head, zd_next) {
		len = strlen(dataset);
		if (dataset[len - 1] == '/')
			len--;	/* Ignore trailing slash */
		if (len < strlen(zd->zd_dataset) &&
		    bcmp(dataset, zd->zd_dataset, len) == 0 &&
		    zd->zd_dataset[len] == '/') {
			if (write)
				*write = 0;
			ret = 1;
			goto end;
		}
	}
end:
	mtx_unlock(&pr->pr_mtx);
	return (ret);
}

static void
zone_destroy(void *arg)
{
	struct zone_dataset_head *head;
	zone_dataset_t *zd;

	head = arg;
	while ((zd = LIST_FIRST(head)) != NULL) {
		LIST_REMOVE(zd, zd_next);
		free(zd, M_ZONES);
	}
	free(head, M_ZONES);
}

uint32_t
zone_get_hostid(void *ptr)
{

	KASSERT(ptr == NULL, ("only NULL pointer supported in %s", __func__));

	return ((uint32_t)curthread->td_ucred->cr_prison->pr_hostid);
}

static void
zone_sysinit(void *arg __unused)
{

	zone_slot = osd_jail_register(zone_destroy, NULL);
}

static void
zone_sysuninit(void *arg __unused)
{

	osd_jail_deregister(zone_slot);
}

SYSINIT(zone_sysinit, SI_SUB_DRIVERS, SI_ORDER_ANY, zone_sysinit, NULL);
SYSUNINIT(zone_sysuninit, SI_SUB_DRIVERS, SI_ORDER_ANY, zone_sysuninit, NULL);
