/*
 *  rpcauth.c
 *
 *  RPC authentication framework
 *
 *  Copyright (c) 2004 The Regents of the University of Michigan.
 *  All rights reserved.
 *
 *  Marius Aamodt Eriksen <marius@umich.edu>
 *
 *  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.
 *  3. Neither the name of the University nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED ``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 REGENTS 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/param.h>
#include <sys/systm.h>
#include <sys/proc.h>
#include <sys/mount.h>
#include <sys/kernel.h>
#include <sys/mbuf.h>
#include <sys/syslog.h>
#include <sys/malloc.h>
#include <sys/uio.h>
#include <sys/lock.h>
#include <sys/signalvar.h>
#include <sys/vnode.h>
#include <sys/namei.h>

#if defined(__APPLE__)
#include <sys/tprintf.h>
#include <sys/buf.h>
#endif


#if defined(__FreeBSD__)
#include <sys/sysent.h>
#endif

#include <sys/syscall.h>
#include <sys/sysctl.h>

#include <sys/domain.h>
#include <sys/protosw.h>
#include <sys/socket.h>
#include <sys/socketvar.h>

#if defined(__FreeBSD__)
#include <sys/mutex.h>
#endif

#if defined(__OpenBSD__)
#include <sys/timeout.h>
#endif

#include <netinet/in.h>
#include <netinet/tcp.h>

#include <nfs4client/nfs4_glue.h>

#include <nfsx/rpcv2.h>
#include <nfsx/xdr_subs.h>
#include <nfsx/nfsproto.h>
#include <nfsxclient/nfs.h>

#include <rpcx/rpcm_subs.h>
#include <rpcx/rpcclnt.h>
#include <rpcx/rpcclnt-private.h>
#include <rpcx/rpc_dev.h>
#include <rpcx/rpcauth.h>

#include <nfs4client/nfs4m_glue.h>

extern struct rpcauth_desc auth_sys_desc;
extern struct rpcauth_desc auth_gss_desc;

static struct rpcauth_desc *_auth_descs[] = {
	&auth_sys_desc,
	&auth_gss_desc,
	NULL,
};

int
rpcauth_create(struct rpcclnt *clnt, int pflavor)
{
	struct rpcauth_desc *d;

	for (d = _auth_descs[0]; d != NULL; d++)
		if (d->auth_pflavors & pflavor) {
			clnt->rc_authdesc = d;
			clnt->rc_auth = (*d->auth_create)(pflavor);
			return (clnt->rc_auth != NULL ? 0 : ENOMEM); /* XXX */
		}

	return (ENOPROTOOPT);
}

/*
 * XXX - we have to export the entire buffer here, too.
 */
int
rpcauth_build_reqhdr(struct rpcclnt *clnt, struct ucred *cred,
    struct mbuf **mhdr, caddr_t *bp, struct mbuf *mbody)
{
	struct rpcauth_desc *d = clnt->rc_authdesc;

	return (d->auth_build_reqhdr != NULL ?
	    (*d->auth_build_reqhdr)(cred, mhdr, bp, mbody) : 0);
}

int
rpcauth_vrfy_rep(struct rpcclnt *clnt, struct ucred *cred,
    struct rpc_reply *reply)
{
	struct rpcauth_desc *d = clnt->rc_authdesc;

	return (d->auth_vrfy_rep != NULL ? (*d->auth_vrfy_rep)(cred, reply) : 0);
}
