/*
 * Copyright 1993, 1994 by Ulrich Khn. All rights reserved.
 *
 * THIS PROGRAM COMES WITH ABSOLUTELY NO WARRANTY, NOT
 * EVEN THE IMPLIED WARRANTIES OF MERCHANTIBILITY OR
 * FITNESS FOR A PARTICULAR PURPOSE. USE AT YOUR OWN
 * RISK.
 */

/*
 * File : auth_mnt.c
 *        make sure that a client requesting a mount is allowed to
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory.h>
#include <types.h>
#include <ctype.h>
#include <stat.h>
#include <netdb.h>
#include <arpa/inet.h>
#include "../xfs/nfs.h"
#include "svc.h"
#include "util.h"
#include "exportent.h"
#include "auth.h"

extern int debug;

#include <syslog.h>


int
check_clientlist(client_info *cl, SVCXPRT *xprt)
{
	struct in_addr addr;

	addr = xprt->xp_raddr.sin_addr;
	for (;  cl;  cl = cl->next)
	{
		if (cl->addr.s_addr != 0UL)
		{
			/* Is this the host we are looking for? */
			if (cl->addr.s_addr == addr.s_addr)
				return 0;
		}
		else
		{
			/* BUG: here we should try to match the hostname again, as it is
			 *      obviously up.
			 */
		}
	}
	return -1;
}


accesslist *
auth_mnt(char *dirname, SVCXPRT *xprt)
{
	accesslist *ac;
	char dir[128];

	path2abs(dirname, dir);

if (debug)
	syslog(LOG_INFO,"auth_mnt: checking `%s'", dir);

	/* Search for the correct entry in the authlist */
	for (ac = authlist;  ac;  ac = ac->next)
	{
if (debug)
	syslog(LOG_INFO, "auth_mnt: checking for `%s'", ac->mountpoint);

		if (!strcmp(dir, ac->mountpoint))
			break;
	}
	if (!ac)
		return NULL;

	/* Now verify that the client is allowed to mount this directory.
	 * Special case: if no hosts given in any list (access=, rw=, root=),
	 * everyone is allowed to mount this.
	 */
	if (!ac->access && !ac->rw_access && !ac->root_access)
		return ac;

	if (check_clientlist(ac->access, xprt) == 0)
		return ac;
	if (check_clientlist(ac->rw_access, xprt) == 0)
		return ac;
	if (check_clientlist(ac->root_access, xprt) == 0)
		return ac;
	return NULL;
}
