/*
 * Copyright (C) 2009 Red Hat <nfs@redhat.com>
 *
 * support/export/v4root.c
 *
 * Routines used to support NFSv4 pseudo roots
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/queue.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

#include <unistd.h>
#include <errno.h>

#include "xlog.h"
#include "exportfs.h"
#include "nfslib.h"
#include "misc.h"
#include "v4root.h"

int v4root_needed;

static nfs_export pseudo_root = {
	.m_next = NULL,
	.m_client = NULL,
	.m_export = {
		.e_hostname = "*",
		.e_path = "/",
		.e_flags = NFSEXP_READONLY | NFSEXP_ROOTSQUASH
				| NFSEXP_NOSUBTREECHECK | NFSEXP_FSID
				| NFSEXP_V4ROOT,
		.e_anonuid = 65534,
		.e_anongid = 65534,
		.e_squids = NULL,
		.e_nsquids = 0,
		.e_sqgids = NULL,
		.e_nsqgids = 0,
		.e_fsid = 0,
		.e_mountpoint = NULL,
	},
	.m_exported = 0,
	.m_xtabent = 1,
	.m_mayexport = 1,
	.m_changed = 0,
	.m_warned = 0,
};

void set_pseudofs_security(struct exportent *pseudo, struct exportent *source)
{
	struct sec_entry *se;
	int i;

	if (source->e_flags & NFSEXP_INSECURE_PORT)
		pseudo->e_flags |= NFSEXP_INSECURE_PORT;
	for (se = source->e_secinfo; se->flav; se++) {
		struct sec_entry *new;

		i = secinfo_addflavor(se->flav, pseudo);
		new = &pseudo->e_secinfo[i];

		if (se->flags & NFSEXP_INSECURE_PORT)
			new->flags |= NFSEXP_INSECURE_PORT;
	}
}

/*
 * Create a pseudo export
 */
static struct exportent *
v4root_create(char *path, nfs_export *export)
{
	nfs_export *exp;
	struct exportent eep;
	struct exportent *curexp = &export->m_export;

	dupexportent(&eep, &pseudo_root.m_export);
	eep.e_hostname = strdup(curexp->e_hostname);
	strncpy(eep.e_path, path, sizeof(eep.e_path));
	if (strcmp(path, "/") != 0)
		eep.e_flags &= ~NFSEXP_FSID;
	set_pseudofs_security(&eep, curexp);
	exp = export_create(&eep, 0);
	if (exp == NULL)
		return NULL;
	xlog(D_CALL, "v4root_create: path '%s'", exp->m_export.e_path);
	return &exp->m_export;
}

/*
 * Make sure the kernel has pseudo root support.
 */
static int
v4root_support(void)
{
	struct export_features *ef;
	static int warned = 0;

	ef = get_export_features();

	if (ef->flags & NFSEXP_V4ROOT)
		return 1;
	if (!warned) {
		xlog(L_WARNING, "Kernel does not have pseudo root support.");
		xlog(L_WARNING, "NFS v4 mounts will be disabled unless fsid=0");
		xlog(L_WARNING, "is specfied in /etc/exports file.");
		warned++;
	}
	return 0;
}

int pseudofs_update(char *hostname, char *path, nfs_export *source)
{
	nfs_export *exp;

	exp = export_lookup(hostname, path, 0);
	if (exp && !(exp->m_export.e_flags & NFSEXP_V4ROOT))
		return 0;
	if (!exp) {
		if (v4root_create(path, source) == NULL) {
			xlog(L_WARNING, "v4root_set: Unable to create "
					"pseudo export for '%s'", path);
			return -ENOMEM;
		}
		return 0;
	}
	/* Update an existing V4ROOT export: */
	set_pseudofs_security(&exp->m_export, &source->m_export);
	return 0;
}

static int v4root_add_parents(nfs_export *exp)
{
	char *hostname = exp->m_export.e_hostname;
	char *path;
	char *ptr;

	path = strdup(exp->m_export.e_path);
	if (!path)
		return -ENOMEM;
	for (ptr = path + 1; ptr; ptr = strchr(ptr, '/')) {
		int ret;
		char saved;

		saved = *ptr;
		*ptr = '\0';
		ret = pseudofs_update(hostname, path, exp);
		if (ret)
			return ret;
		*ptr = saved;
		ptr++;
	}
	free(path);
	return 0;
}

/*
 * Create pseudo exports by running through the real export
 * looking at the components of the path that make up the export.
 * Those path components, if not exported, will become pseudo
 * exports allowing them to be found when the kernel does an upcall
 * looking for components of the v4 mount.
 */
void
v4root_set()
{
	nfs_export	*exp;
	int	i, ret;

	if (!v4root_needed)
		return;
	if (!v4root_support())
		return;

	for (i = 0; i < MCL_MAXTYPES; i++) {
		for (exp = exportlist[i].p_head; exp; exp = exp->m_next) {
			if (exp->m_export.e_flags & NFSEXP_V4ROOT)
				/*
				 * We just added this one, so its
				 * parents are already dealt with!
				 */
				continue;

			ret = v4root_add_parents(exp);
			/* XXX: error handling! */
		}
	}
}
