138494Sobrien/* 2174294Sobrien * Copyright (c) 1997-2006 Erez Zadok 338494Sobrien * Copyright (c) 1990 Jan-Simon Pendry 438494Sobrien * Copyright (c) 1990 Imperial College of Science, Technology & Medicine 538494Sobrien * Copyright (c) 1990 The Regents of the University of California. 638494Sobrien * All rights reserved. 738494Sobrien * 838494Sobrien * This code is derived from software contributed to Berkeley by 938494Sobrien * Jan-Simon Pendry at Imperial College, London. 1038494Sobrien * 1138494Sobrien * Redistribution and use in source and binary forms, with or without 1238494Sobrien * modification, are permitted provided that the following conditions 1338494Sobrien * are met: 1438494Sobrien * 1. Redistributions of source code must retain the above copyright 1538494Sobrien * notice, this list of conditions and the following disclaimer. 1638494Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1738494Sobrien * notice, this list of conditions and the following disclaimer in the 1838494Sobrien * documentation and/or other materials provided with the distribution. 1938494Sobrien * 3. All advertising materials mentioning features or use of this software 2042629Sobrien * must display the following acknowledgment: 2138494Sobrien * This product includes software developed by the University of 2238494Sobrien * California, Berkeley and its contributors. 2338494Sobrien * 4. Neither the name of the University nor the names of its contributors 2438494Sobrien * may be used to endorse or promote products derived from this software 2538494Sobrien * without specific prior written permission. 2638494Sobrien * 2738494Sobrien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2838494Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2938494Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 3038494Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 3138494Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3238494Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3338494Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3438494Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3538494Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3638494Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3738494Sobrien * SUCH DAMAGE. 3838494Sobrien * 3938494Sobrien * 40174294Sobrien * File: am-utils/libamu/misc_rpc.c 4138494Sobrien * 4238494Sobrien */ 4338494Sobrien 4438494Sobrien/* 4538494Sobrien * Additions to Sun RPC. 4638494Sobrien */ 4738494Sobrien 4838494Sobrien#ifdef HAVE_CONFIG_H 4938494Sobrien# include <config.h> 5038494Sobrien#endif /* HAVE_CONFIG_H */ 5138494Sobrien#include <am_defs.h> 5238494Sobrien#include <amu.h> 5338494Sobrien 5438494Sobrien/* 5538494Sobrien * Some systems renamed _seterr_reply to __seterr_reply (with two 5638494Sobrien * leading underscores) 5738494Sobrien */ 5838494Sobrien#if !defined(HAVE__SETERR_REPLY) && defined(HAVE___SETERR_REPLY) 5938494Sobrien# define _seterr_reply __seterr_reply 6038494Sobrien#endif /* !defined(HAVE__SETERR_REPLY) && defined(HAVE___SETERR_REPLY) */ 6138494Sobrien 6238494Sobrien 6338494Sobrienvoid 6438494Sobrienrpc_msg_init(struct rpc_msg *mp, u_long prog, u_long vers, u_long proc) 6538494Sobrien{ 6638494Sobrien /* 6742629Sobrien * Initialize the message 6838494Sobrien */ 6938494Sobrien memset((voidp) mp, 0, sizeof(*mp)); 7038494Sobrien mp->rm_xid = 0; 7138494Sobrien mp->rm_direction = CALL; 7238494Sobrien mp->rm_call.cb_rpcvers = RPC_MSG_VERSION; 7338494Sobrien mp->rm_call.cb_prog = prog; 7438494Sobrien mp->rm_call.cb_vers = vers; 7538494Sobrien mp->rm_call.cb_proc = proc; 7638494Sobrien} 7738494Sobrien 7838494Sobrien 7938494Sobrien/* 8038494Sobrien * Field reply to call to mountd 8138494Sobrien */ 8238494Sobrienint 8338494Sobrienpickup_rpc_reply(voidp pkt, int len, voidp where, XDRPROC_T_TYPE where_xdr) 8438494Sobrien{ 8538494Sobrien XDR reply_xdr; 8638494Sobrien int ok; 8738494Sobrien struct rpc_err err; 8838494Sobrien struct rpc_msg reply_msg; 8938494Sobrien int error = 0; 9038494Sobrien 9138494Sobrien /* memset((voidp) &err, 0, sizeof(err)); */ 9238494Sobrien memset((voidp) &reply_msg, 0, sizeof(reply_msg)); 9338494Sobrien memset((voidp) &reply_xdr, 0, sizeof(reply_xdr)); 9438494Sobrien 95174294Sobrien reply_msg.acpted_rply.ar_results.where = where; 9638494Sobrien reply_msg.acpted_rply.ar_results.proc = where_xdr; 9738494Sobrien 9838494Sobrien xdrmem_create(&reply_xdr, pkt, len, XDR_DECODE); 9938494Sobrien 10038494Sobrien ok = xdr_replymsg(&reply_xdr, &reply_msg); 10138494Sobrien if (!ok) { 10238494Sobrien error = EIO; 10338494Sobrien goto drop; 10438494Sobrien } 10538494Sobrien _seterr_reply(&reply_msg, &err); 10638494Sobrien if (err.re_status != RPC_SUCCESS) { 10738494Sobrien error = EIO; 10838494Sobrien goto drop; 10938494Sobrien } 11038494Sobrien 11138494Sobriendrop: 11238494Sobrien if (reply_msg.rm_reply.rp_stat == MSG_ACCEPTED && 11338494Sobrien reply_msg.acpted_rply.ar_verf.oa_base) { 11438494Sobrien reply_xdr.x_op = XDR_FREE; 11538494Sobrien (void) xdr_opaque_auth(&reply_xdr, 11638494Sobrien &reply_msg.acpted_rply.ar_verf); 11738494Sobrien } 11838494Sobrien xdr_destroy(&reply_xdr); 11938494Sobrien 12038494Sobrien return error; 12138494Sobrien} 12238494Sobrien 12338494Sobrien 12438494Sobrienint 12538494Sobrienmake_rpc_packet(char *buf, int buflen, u_long proc, struct rpc_msg *mp, voidp arg, XDRPROC_T_TYPE arg_xdr, AUTH *auth) 12638494Sobrien{ 12738494Sobrien XDR msg_xdr; 12838494Sobrien int len; 129119679Smbr /* 130119679Smbr * Never cast pointers between different integer types, it breaks badly 131119679Smbr * on big-endian platforms if those types have different sizes. 132119679Smbr * 133119679Smbr * Cast to a local variable instead, and use that variable's address. 134119679Smbr */ 135119679Smbr enum_t local_proc = (enum_t) proc; 13638494Sobrien 13738494Sobrien xdrmem_create(&msg_xdr, buf, buflen, XDR_ENCODE); 13838494Sobrien 13938494Sobrien /* 14038494Sobrien * Basic protocol header 14138494Sobrien */ 14238494Sobrien if (!xdr_callhdr(&msg_xdr, mp)) 14338494Sobrien return -EIO; 14438494Sobrien 14538494Sobrien /* 14638494Sobrien * Called procedure number 14738494Sobrien */ 148119679Smbr if (!xdr_enum(&msg_xdr, &local_proc)) 14938494Sobrien return -EIO; 15038494Sobrien 15138494Sobrien /* 15238494Sobrien * Authorization 15338494Sobrien */ 15438494Sobrien if (!AUTH_MARSHALL(auth, &msg_xdr)) 15538494Sobrien return -EIO; 15638494Sobrien 15738494Sobrien /* 15838494Sobrien * Arguments 15938494Sobrien */ 16038494Sobrien if (!(*arg_xdr) (&msg_xdr, arg)) 16138494Sobrien return -EIO; 16238494Sobrien 16338494Sobrien /* 16438494Sobrien * Determine length 16538494Sobrien */ 16638494Sobrien len = xdr_getpos(&msg_xdr); 16738494Sobrien 16838494Sobrien /* 16938494Sobrien * Throw away xdr 17038494Sobrien */ 17138494Sobrien xdr_destroy(&msg_xdr); 17238494Sobrien 17338494Sobrien return len; 17438494Sobrien} 17582794Sobrien 17682794Sobrien 17782794Sobrien/* get uid/gid from RPC credentials */ 17882794Sobrienint 17982794Sobriengetcreds(struct svc_req *rp, uid_t *u, gid_t *g, SVCXPRT *nfsxprt) 18082794Sobrien{ 18182794Sobrien struct authunix_parms *aup = (struct authunix_parms *) NULL; 18282794Sobrien#ifdef HAVE_RPC_AUTH_DES_H 18382794Sobrien struct authdes_cred *adp; 18482794Sobrien#endif /* HAVE_RPC_AUTH_DES_H */ 18582794Sobrien 18682794Sobrien switch (rp->rq_cred.oa_flavor) { 18782794Sobrien 18882794Sobrien case AUTH_UNIX: 18982794Sobrien aup = (struct authunix_parms *) rp->rq_clntcred; 19082794Sobrien *u = aup->aup_uid; 19182794Sobrien *g = aup->aup_gid; 19282794Sobrien break; 19382794Sobrien 19482794Sobrien#ifdef HAVE_RPC_AUTH_DES_H 19582794Sobrien case AUTH_DES: 19682794Sobrien adp = (struct authdes_cred *) rp->rq_clntcred; 19782794Sobrien *g = INVALIDID; /* some unknown group id */ 19882794Sobrien if (sscanf(adp->adc_fullname.name, "unix.%lu@", (u_long *) u) == 1) 19982794Sobrien break; 20082794Sobrien /* fall through */ 20182794Sobrien#endif /* HAVE_RPC_AUTH_DES_H */ 20282794Sobrien 20382794Sobrien default: 20482794Sobrien *u = *g = INVALIDID; /* just in case */ 20582794Sobrien svcerr_weakauth(nfsxprt); 20682794Sobrien return -1; 20782794Sobrien } 20882794Sobrien 20982794Sobrien return 0; /* everything is ok */ 21082794Sobrien} 211