1/* 2 * Copyright (c) 1997-2006 Erez Zadok 3 * Copyright (c) 1990 Jan-Simon Pendry 4 * Copyright (c) 1990 Imperial College of Science, Technology & Medicine 5 * Copyright (c) 1990 The Regents of the University of California. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to Berkeley by 9 * Jan-Simon Pendry at Imperial College, London. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgment: 21 * This product includes software developed by the University of 22 * California, Berkeley and its contributors. 23 * 4. Neither the name of the University nor the names of its contributors 24 * may be used to endorse or promote products derived from this software 25 * without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37 * SUCH DAMAGE. 38 * 39 * 40 * File: am-utils/libamu/misc_rpc.c 41 * 42 */ 43 44/* 45 * Additions to Sun RPC. 46 */ 47 48#ifdef HAVE_CONFIG_H 49# include <config.h> 50#endif /* HAVE_CONFIG_H */ 51#include <am_defs.h> 52#include <amu.h> 53 54/* 55 * Some systems renamed _seterr_reply to __seterr_reply (with two 56 * leading underscores) 57 */ 58#if !defined(HAVE__SETERR_REPLY) && defined(HAVE___SETERR_REPLY) 59# define _seterr_reply __seterr_reply 60#endif /* !defined(HAVE__SETERR_REPLY) && defined(HAVE___SETERR_REPLY) */ 61 62 63void 64rpc_msg_init(struct rpc_msg *mp, u_long prog, u_long vers, u_long proc) 65{ 66 /* 67 * Initialize the message 68 */ 69 memset((voidp) mp, 0, sizeof(*mp)); 70 mp->rm_xid = 0; 71 mp->rm_direction = CALL; 72 mp->rm_call.cb_rpcvers = RPC_MSG_VERSION; 73 mp->rm_call.cb_prog = prog; 74 mp->rm_call.cb_vers = vers; 75 mp->rm_call.cb_proc = proc; 76} 77 78 79/* 80 * Field reply to call to mountd 81 */ 82int 83pickup_rpc_reply(voidp pkt, int len, voidp where, XDRPROC_T_TYPE where_xdr) 84{ 85 XDR reply_xdr; 86 int ok; 87 struct rpc_err err; 88 struct rpc_msg reply_msg; 89 int error = 0; 90 91 /* memset((voidp) &err, 0, sizeof(err)); */ 92 memset((voidp) &reply_msg, 0, sizeof(reply_msg)); 93 memset((voidp) &reply_xdr, 0, sizeof(reply_xdr)); 94 95 reply_msg.acpted_rply.ar_results.where = where; 96 reply_msg.acpted_rply.ar_results.proc = where_xdr; 97 98 xdrmem_create(&reply_xdr, pkt, len, XDR_DECODE); 99 100 ok = xdr_replymsg(&reply_xdr, &reply_msg); 101 if (!ok) { 102 error = EIO; 103 goto drop; 104 } 105 _seterr_reply(&reply_msg, &err); 106 if (err.re_status != RPC_SUCCESS) { 107 error = EIO; 108 goto drop; 109 } 110 111drop: 112 if (reply_msg.rm_reply.rp_stat == MSG_ACCEPTED && 113 reply_msg.acpted_rply.ar_verf.oa_base) { 114 reply_xdr.x_op = XDR_FREE; 115 (void) xdr_opaque_auth(&reply_xdr, 116 &reply_msg.acpted_rply.ar_verf); 117 } 118 xdr_destroy(&reply_xdr); 119 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