/*
 * utils/mountd/auth.c
 *
 * Authentication procedures for mountd.
 *
 * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
 */

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

#include <sys/stat.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <unistd.h>
#include "misc.h"
#include "nfslib.h"
#include "exportfs.h"
#include "mountd.h"
#include "xmalloc.h"
#include "v4root.h"

enum auth_error
{
  bad_path,
  unknown_host,
  no_entry,
  not_exported,
  illegal_port,
  success
};

static void		auth_fixpath(char *path);
static char	*export_file = NULL;
static nfs_export my_exp;
static nfs_client my_client;

extern int new_cache;
extern int use_ipaddr;

void
auth_init(char *exports)
{

	export_file = exports;
	auth_reload();
	xtab_mount_write();
}

/*
 * A client can match many different netgroups and it's tough to know
 * beforehand whether it will. If the concatenated string of netgroup
 * m_hostnames is >512 bytes, then enable the "use_ipaddr" mode. This
 * makes mountd change how it matches a client ip address when a mount
 * request comes in. It's more efficient at handling netgroups at the
 * expense of larger kernel caches.
 */
static void
check_useipaddr(void)
{
	nfs_client *clp;
	int old_use_ipaddr = use_ipaddr;
	unsigned int len = 0;

	/* add length of m_hostname + 1 for the comma */
	for (clp = clientlist[MCL_NETGROUP]; clp; clp = clp->m_next)
		len += (strlen(clp->m_hostname) + 1);

	if (len > (NFSCLNT_IDMAX / 2))
		use_ipaddr = 1;
	else
		use_ipaddr = 0;

	if (use_ipaddr != old_use_ipaddr)
		cache_flush(1);
}

unsigned int
auth_reload()
{
	struct stat		stb;
	static ino_t		last_inode;
	static int		last_fd;
	static unsigned int	counter;
	int			fd;

	if ((fd = open(_PATH_ETAB, O_RDONLY)) < 0) {
		xlog(L_FATAL, "couldn't open %s", _PATH_ETAB);
	} else if (fstat(fd, &stb) < 0) {
		xlog(L_FATAL, "couldn't stat %s", _PATH_ETAB);
	} else if (stb.st_ino == last_inode) {
		close(fd);
		return counter;
	} else {
		close(last_fd);
		last_fd = fd;
		last_inode = stb.st_ino;
	}

	export_freeall();
	memset(&my_client, 0, sizeof(my_client));
	xtab_export_read();
	check_useipaddr();
	v4root_set();

	++counter;

	return counter;
}

static char *get_client_hostname(struct sockaddr_in *caller, struct hostent *hp, enum auth_error *error)
{
	char *n;

	if (use_ipaddr)
		return strdup(inet_ntoa(caller->sin_addr));
	n = client_compose(hp);
	*error = unknown_host;
	if (!n)
		return NULL;
	if (*n)
		return n;
	free(n);
	return strdup("DEFAULT");
}

/* return static nfs_export with details filled in */
static nfs_export *
auth_authenticate_newcache(char *what, struct sockaddr_in *caller,
			   char *path, struct hostent *hp,
			   enum auth_error *error)
{
	nfs_export *exp;
	int i;

	free(my_client.m_hostname);

	my_client.m_hostname = get_client_hostname(caller, hp, error);
	if (my_client.m_hostname == NULL)
		return NULL;

	my_client.m_naddr = 1;
	my_client.m_addrlist[0] = caller->sin_addr;
	my_exp.m_client = &my_client;

	exp = NULL;
	for (i = 0; !exp && i < MCL_MAXTYPES; i++)
		for (exp = exportlist[i].p_head; exp; exp = exp->m_next) {
			if (strcmp(path, exp->m_export.e_path))
				continue;
			if (!use_ipaddr && !client_member(my_client.m_hostname, exp->m_client->m_hostname))
				continue;
			if (use_ipaddr && !client_check(exp->m_client, hp))
				continue;
			break;
		}
	*error = not_exported;
	if (!exp)
		return NULL;

	my_exp.m_export = exp->m_export;
	exp = &my_exp;
	return exp;
}

static nfs_export *
auth_authenticate_internal(char *what, struct sockaddr_in *caller,
			   char *path, struct hostent *hp,
			   enum auth_error *error)
{
	nfs_export *exp;

	if (new_cache) {
		exp = auth_authenticate_newcache(what, caller, path, hp, error);
		if (!exp)
			return NULL;
	} else {
		if (!(exp = export_find(hp, path))) {
			*error = no_entry;
			return NULL;
		}
	}
	if (exp->m_export.e_flags & NFSEXP_V4ROOT) {
		*error = no_entry;
		return NULL;
	}
	if (!(exp->m_export.e_flags & NFSEXP_INSECURE_PORT) &&
		     ntohs(caller->sin_port) >= IPPORT_RESERVED) {
		*error = illegal_port;
		return NULL;
	}
	*error = success;

	return exp;
}

nfs_export *
auth_authenticate(char *what, struct sockaddr_in *caller, char *path)
{
	nfs_export	*exp = NULL;
	char		epath[MAXPATHLEN+1];
	char		*p = NULL;
	struct hostent	*hp = NULL;
	struct in_addr	addr = caller->sin_addr;
	enum auth_error	error = bad_path;

	if (path [0] != '/') {
		xlog(L_WARNING, "bad path in %s request from %s: \"%s\"",
		     what, inet_ntoa(addr), path);
		return exp;
	}

	strncpy(epath, path, sizeof (epath) - 1);
	epath[sizeof (epath) - 1] = '\0';
	auth_fixpath(epath); /* strip duplicate '/' etc */

	hp = client_resolve(caller->sin_addr);
	if (!hp)
		return exp;

	/* Try the longest matching exported pathname. */
	while (1) {
		exp = auth_authenticate_internal(what, caller, epath,
						 hp, &error);
		if (exp || (error != not_exported && error != no_entry))
			break;
		/* We have to treat the root, "/", specially. */
		if (p == &epath[1]) break;
		p = strrchr(epath, '/');
		if (p == epath) p++;
		*p = '\0';
	}

	switch (error) {
	case bad_path:
		xlog(L_WARNING, "bad path in %s request from %s: \"%s\"",
		     what, inet_ntoa(addr), path);
		break;

	case unknown_host:
		xlog(L_WARNING, "refused %s request from %s for %s (%s): unmatched host",
		     what, inet_ntoa(addr), path, epath);
		break;

	case no_entry:
		xlog(L_WARNING, "refused %s request from %s for %s (%s): no export entry",
		     what, hp->h_name, path, epath);
		break;

	case not_exported:
		xlog(L_WARNING, "refused %s request from %s for %s (%s): not exported",
		     what, hp->h_name, path, epath);
		break;

	case illegal_port:
		xlog(L_WARNING, "refused %s request from %s for %s (%s): illegal port %d",
		     what, hp->h_name, path, epath, ntohs(caller->sin_port));
		break;

	case success:
		xlog(L_NOTICE, "authenticated %s request from %s:%d for %s (%s)",
		     what, hp->h_name, ntohs(caller->sin_port), path, epath);
		break;
	default:
		xlog(L_NOTICE, "%s request from %s:%d for %s (%s) gave %d",
		     what, hp->h_name, ntohs(caller->sin_port), path, epath, error);
	}

	if (hp)
		free (hp);

	return exp;
}

static void
auth_fixpath(char *path)
{
	char	*sp, *cp;

	for (sp = cp = path; *sp; sp++) {
		if (*sp != '/' || sp[1] != '/')
			*cp++ = *sp;
	}
	while (cp > path+1 && cp[-1] == '/')
		cp--;
	*cp = '\0';
}
