/*
 *  rpcauth_sys.c
 *
 *  RPC UID/GID authentication
 *
 *  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/types.h>
#include <sys/ucred.h>
#include <sys/mbuf.h>
#include <sys/systm.h>

#include <nfsx/rpcv2.h>
#include <nfsx/xdr_subs.h>

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

static void *sys_create(int);
static int   sys_build_reqhdr(struct ucred *, struct mbuf **,
                 caddr_t *, struct mbuf *mbody);

struct rpcauth_desc auth_sys_desc = {
	.auth_create = sys_create,
	.auth_build_reqhdr = sys_build_reqhdr,

	.auth_pflavors = RPCAUTH_PFLAVOR_SYS,
};

static void *
sys_create(int pflavor)
{
	return (&auth_sys_desc);
}

static int
sys_build_reqhdr(struct ucred *cred, struct mbuf **mbp,
    caddr_t *bposp, struct mbuf *mbody)
{
	size_t authsiz, verfsiz;
	u_int32_t mlen, grpsiz;
	register struct mbuf *mb, *mb2;
	caddr_t bpos;
	u_int32_t *tl;
	int i;

	printf("auth_sys building reqhdr\n");

	authsiz = (5 + cred->cr_ngroups) * RPCX_UNSIGNED;
	verfsiz = 0;

	mlen = rpcm_rndup(authsiz) + rpcm_rndup(verfsiz) + 4 * RPCX_UNSIGNED;

	mb = *mbp;
	bpos = *bposp;

	rpcm_build(tl, u_int32_t *, mlen);

	*bposp = bpos;
	*mbp = mb;

	*tl++ = txdr_unsigned(RPCAUTH_UNIX);
	*tl++ = txdr_unsigned(authsiz);

	*tl++ = 0;
	*tl++ = 0; 

	*tl++ = txdr_unsigned(cred->cr_uid);
	*tl++ = txdr_unsigned(cred->cr_groups[0]);
	grpsiz = cred->cr_ngroups;
	*tl++ = txdr_unsigned(grpsiz);
	/* XXX: groups[0] is already sent... */
	for (i = 0 ; i < grpsiz ; i++)
		*tl++ = txdr_unsigned(cred->cr_groups[i]);

	/* null verification header */
	*tl++ = txdr_unsigned(RPCAUTH_NULL);
	*tl++ = 0;

	return (0);
}
