/* $NetBSD: authunix_prot.c,v 1.12 2000/01/22 22:19:17 mycroft Exp $ */12/*-3* SPDX-License-Identifier: BSD-3-Clause4*5* Copyright (c) 2009, Sun Microsystems, Inc.6* All rights reserved.7*8* Redistribution and use in source and binary forms, with or without9* modification, are permitted provided that the following conditions are met:10* - Redistributions of source code must retain the above copyright notice,11* this list of conditions and the following disclaimer.12* - Redistributions in binary form must reproduce the above copyright notice,13* this list of conditions and the following disclaimer in the documentation14* and/or other materials provided with the distribution.15* - Neither the name of Sun Microsystems, Inc. nor the names of its16* contributors may be used to endorse or promote products derived17* from this software without specific prior written permission.18*19* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"20* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE21* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE22* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE23* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR24* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF25* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS26* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN27* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)28* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE29* POSSIBILITY OF SUCH DAMAGE.30*/3132/*33* authunix_prot.c34* XDR for UNIX style authentication parameters for RPC35*36* Copyright (C) 1984, Sun Microsystems, Inc.37*/3839#include <sys/param.h>40#include <sys/jail.h>41#include <sys/libkern.h>42#include <sys/ucred.h>4344#include <rpc/types.h>45#include <rpc/xdr.h>46#include <rpc/auth.h>4748#include <rpc/rpc_com.h>4950/*51* XDR for unix authentication parameters.52*/53bool_t54xdr_authunix_parms(XDR *xdrs, uint32_t *time, struct xucred *cred)55{56uint32_t namelen;57uint32_t supp_ngroups, i;58uint32_t junk;59char hostbuf[MAXHOSTNAMELEN];6061if (xdrs->x_op == XDR_FREE)62/* This function does not allocate auxiliary memory. */63return (TRUE);6465if (xdrs->x_op == XDR_ENCODE) {66getcredhostname(NULL, hostbuf, sizeof(hostbuf));67namelen = strlen(hostbuf);68if (namelen > AUTH_SYS_MAX_HOSTNAME)69namelen = AUTH_SYS_MAX_HOSTNAME;70} else71namelen = 0;7273if (!xdr_uint32_t(xdrs, time) || !xdr_uint32_t(xdrs, &namelen))74return (FALSE);7576/*77* Ignore the hostname on decode.78*/79if (xdrs->x_op == XDR_ENCODE) {80if (!xdr_opaque(xdrs, hostbuf, namelen))81return (FALSE);82} else {83if (namelen > AUTH_SYS_MAX_HOSTNAME)84return (FALSE);85xdr_setpos(xdrs, xdr_getpos(xdrs) + RNDUP(namelen));86}8788if (!xdr_uint32_t(xdrs, &cred->cr_uid))89return (FALSE);9091/*92* Safety check: The protocol needs at least one group (access to93* 'cr_gid', decrementation of 'cr_ngroups' below).94*/95if (xdrs->x_op == XDR_ENCODE && cred->cr_ngroups == 0)96return (FALSE);97if (!xdr_uint32_t(xdrs, &cred->cr_gid))98return (FALSE);99100if (xdrs->x_op == XDR_ENCODE) {101/*102* Note that this is a 'struct xucred', which still has the103* historical layout where the effective GID is in cr_groups[0]104* and is accounted in 'cr_ngroups'. We substract 1 to obtain105* the number of "supplementary" groups, passed in the AUTH_SYS106* credentials variable-length array called gids[] in RFC 5531.107*/108MPASS(cred->cr_ngroups <= XU_NGROUPS);109supp_ngroups = cred->cr_ngroups - 1;110if (supp_ngroups > AUTH_SYS_MAX_GROUPS)111/* With current values, this should never execute. */112supp_ngroups = AUTH_SYS_MAX_GROUPS;113}114115if (!xdr_uint32_t(xdrs, &supp_ngroups))116return (FALSE);117118/*119* Because we cannot store more than XU_NGROUPS in total (16 at time of120* this writing), for now we choose to be strict with respect to RFC121* 5531's maximum number of supplementary groups (AUTH_SYS_MAX_GROUPS).122* That would also be an accidental DoS prevention measure if the123* request handling code didn't try to reassemble it in full without any124* size limits. Although AUTH_SYS_MAX_GROUPS and XU_NGROUPS are equal,125* since the latter includes the "effective" GID, we cannot store the126* last group of a message with exactly AUTH_SYS_MAX_GROUPS127* supplementary groups. We accept such messages so as not to violate128* the protocol, silently dropping the last group on the floor.129*/130131if (xdrs->x_op != XDR_ENCODE && supp_ngroups > AUTH_SYS_MAX_GROUPS)132return (FALSE);133134junk = 0;135for (i = 0; i < supp_ngroups; ++i)136if (!xdr_uint32_t(xdrs, i < XU_NGROUPS - 1 ?137&cred->cr_sgroups[i] : &junk))138return (FALSE);139140if (xdrs->x_op != XDR_ENCODE)141cred->cr_ngroups = MIN(supp_ngroups + 1, XU_NGROUPS);142143return (TRUE);144}145146147