150276Speter/* 2166124Srafan * Copyright (c) 1997-2006 Erez Zadok 350276Speter * Copyright (c) 1990 Jan-Simon Pendry 450276Speter * Copyright (c) 1990 Imperial College of Science, Technology & Medicine 550276Speter * Copyright (c) 1990 The Regents of the University of California. 650276Speter * All rights reserved. 750276Speter * 850276Speter * This code is derived from software contributed to Berkeley by 950276Speter * Jan-Simon Pendry at Imperial College, London. 1050276Speter * 1150276Speter * Redistribution and use in source and binary forms, with or without 1250276Speter * modification, are permitted provided that the following conditions 1350276Speter * are met: 1450276Speter * 1. Redistributions of source code must retain the above copyright 1550276Speter * notice, this list of conditions and the following disclaimer. 1650276Speter * 2. Redistributions in binary form must reproduce the above copyright 1750276Speter * notice, this list of conditions and the following disclaimer in the 1850276Speter * documentation and/or other materials provided with the distribution. 1950276Speter * 3. All advertising materials mentioning features or use of this software 2050276Speter * must display the following acknowledgment: 2150276Speter * This product includes software developed by the University of 2250276Speter * California, Berkeley and its contributors. 2350276Speter * 4. Neither the name of the University nor the names of its contributors 2450276Speter * may be used to endorse or promote products derived from this software 2550276Speter * without specific prior written permission. 2650276Speter * 2750276Speter * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2850276Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2950276Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30166124Srafan * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 3150276Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32166124Srafan * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3350276Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3450276Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35166124Srafan * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3650276Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3750276Speter * SUCH DAMAGE. 3850276Speter * 3950276Speter * 4050276Speter * File: am-utils/libamu/misc_rpc.c 4150276Speter * 4276726Speter */ 4350276Speter 4450276Speter/* 45166124Srafan * Additions to Sun RPC. 4650276Speter */ 4750276Speter 4850276Speter#ifdef HAVE_CONFIG_H 49166124Srafan# include <config.h> 50166124Srafan#endif /* HAVE_CONFIG_H */ 51166124Srafan#include <am_defs.h> 52166124Srafan#include <amu.h> 53166124Srafan 54166124Srafan/* 55166124Srafan * Some systems renamed _seterr_reply to __seterr_reply (with two 56166124Srafan * leading underscores) 57166124Srafan */ 58166124Srafan#if !defined(HAVE__SETERR_REPLY) && defined(HAVE___SETERR_REPLY) 59166124Srafan# define _seterr_reply __seterr_reply 60166124Srafan#endif /* !defined(HAVE__SETERR_REPLY) && defined(HAVE___SETERR_REPLY) */ 6150276Speter 6250276Speter 6350276Spetervoid 6450276Speterrpc_msg_init(struct rpc_msg *mp, u_long prog, u_long vers, u_long proc) 6550276Speter{ 6650276Speter /* 6776726Speter * Initialize the message 6850276Speter */ 69166124Srafan memset((voidp) mp, 0, sizeof(*mp)); 70166124Srafan mp->rm_xid = 0; 7150276Speter mp->rm_direction = CALL; 7250276Speter mp->rm_call.cb_rpcvers = RPC_MSG_VERSION; 7350276Speter mp->rm_call.cb_prog = prog; 74166124Srafan mp->rm_call.cb_vers = vers; 7550276Speter mp->rm_call.cb_proc = proc; 76166124Srafan} 7750276Speter 7850276Speter 7950276Speter/* 8050276Speter * Field reply to call to mountd 8150276Speter */ 8250276Speterint 8350276Speterpickup_rpc_reply(voidp pkt, int len, voidp where, XDRPROC_T_TYPE where_xdr) 84166124Srafan{ 8550276Speter XDR reply_xdr; 8650276Speter int ok; 87166124Srafan struct rpc_err err; 8850276Speter struct rpc_msg reply_msg; 89166124Srafan int error = 0; 9050276Speter 9150276Speter /* memset((voidp) &err, 0, sizeof(err)); */ 9250276Speter memset((voidp) &reply_msg, 0, sizeof(reply_msg)); 9350276Speter memset((voidp) &reply_xdr, 0, sizeof(reply_xdr)); 94166124Srafan 9550276Speter reply_msg.acpted_rply.ar_results.where = where; 9650276Speter reply_msg.acpted_rply.ar_results.proc = where_xdr; 97166124Srafan 9850276Speter xdrmem_create(&reply_xdr, pkt, len, XDR_DECODE); 99166124Srafan 10050276Speter ok = xdr_replymsg(&reply_xdr, &reply_msg); 10150276Speter if (!ok) { 10250276Speter error = EIO; 10350276Speter goto drop; 10450276Speter } 10550276Speter _seterr_reply(&reply_msg, &err); 10650276Speter if (err.re_status != RPC_SUCCESS) { 107166124Srafan error = EIO; 10850276Speter goto drop; 10950276Speter } 11050276Speter 111166124Srafandrop: 112166124Srafan if (reply_msg.rm_reply.rp_stat == MSG_ACCEPTED && 11350276Speter reply_msg.acpted_rply.ar_verf.oa_base) { 11450276Speter reply_xdr.x_op = XDR_FREE; 11550276Speter (void) xdr_opaque_auth(&reply_xdr, 11650276Speter &reply_msg.acpted_rply.ar_verf); 117166124Srafan } 11850276Speter xdr_destroy(&reply_xdr); 11950276Speter 120 return error; 121} 122 123 124int 125make_rpc_packet(char *buf, int buflen, u_long proc, struct rpc_msg *mp, voidp arg, XDRPROC_T_TYPE arg_xdr, AUTH *auth) 126{ 127 XDR msg_xdr; 128 int len; 129 /* 130 * Never cast pointers between different integer types, it breaks badly 131 * on big-endian platforms if those types have different sizes. 132 * 133 * Cast to a local variable instead, and use that variable's address. 134 */ 135 enum_t local_proc = (enum_t) proc; 136 137 xdrmem_create(&msg_xdr, buf, buflen, XDR_ENCODE); 138 139 /* 140 * Basic protocol header 141 */ 142 if (!xdr_callhdr(&msg_xdr, mp)) 143 return -EIO; 144 145 /* 146 * Called procedure number 147 */ 148 if (!xdr_enum(&msg_xdr, &local_proc)) 149 return -EIO; 150 151 /* 152 * Authorization 153 */ 154 if (!AUTH_MARSHALL(auth, &msg_xdr)) 155 return -EIO; 156 157 /* 158 * Arguments 159 */ 160 if (!(*arg_xdr) (&msg_xdr, arg)) 161 return -EIO; 162 163 /* 164 * Determine length 165 */ 166 len = xdr_getpos(&msg_xdr); 167 168 /* 169 * Throw away xdr 170 */ 171 xdr_destroy(&msg_xdr); 172 173 return len; 174} 175 176 177/* get uid/gid from RPC credentials */ 178int 179getcreds(struct svc_req *rp, uid_t *u, gid_t *g, SVCXPRT *nfsxprt) 180{ 181 struct authunix_parms *aup = (struct authunix_parms *) NULL; 182#ifdef HAVE_RPC_AUTH_DES_H 183 struct authdes_cred *adp; 184#endif /* HAVE_RPC_AUTH_DES_H */ 185 186 switch (rp->rq_cred.oa_flavor) { 187 188 case AUTH_UNIX: 189 aup = (struct authunix_parms *) rp->rq_clntcred; 190 *u = aup->aup_uid; 191 *g = aup->aup_gid; 192 break; 193 194#ifdef HAVE_RPC_AUTH_DES_H 195 case AUTH_DES: 196 adp = (struct authdes_cred *) rp->rq_clntcred; 197 *g = INVALIDID; /* some unknown group id */ 198 if (sscanf(adp->adc_fullname.name, "unix.%lu@", (u_long *) u) == 1) 199 break; 200 /* fall through */ 201#endif /* HAVE_RPC_AUTH_DES_H */ 202 203 default: 204 *u = *g = INVALIDID; /* just in case */ 205 svcerr_weakauth(nfsxprt); 206 return -1; 207 } 208 209 return 0; /* everything is ok */ 210} 211