Home | History | Annotate | Line # | Download | only in libamu
      1 /*	$NetBSD: misc_rpc.c,v 1.1.1.3 2015/01/17 16:34:18 christos Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1997-2014 Erez Zadok
      5  * Copyright (c) 1990 Jan-Simon Pendry
      6  * Copyright (c) 1990 Imperial College of Science, Technology & Medicine
      7  * Copyright (c) 1990 The Regents of the University of California.
      8  * All rights reserved.
      9  *
     10  * This code is derived from software contributed to Berkeley by
     11  * Jan-Simon Pendry at Imperial College, London.
     12  *
     13  * Redistribution and use in source and binary forms, with or without
     14  * modification, are permitted provided that the following conditions
     15  * are met:
     16  * 1. Redistributions of source code must retain the above copyright
     17  *    notice, this list of conditions and the following disclaimer.
     18  * 2. Redistributions in binary form must reproduce the above copyright
     19  *    notice, this list of conditions and the following disclaimer in the
     20  *    documentation and/or other materials provided with the distribution.
     21  * 3. Neither the name of the University nor the names of its contributors
     22  *    may be used to endorse or promote products derived from this software
     23  *    without specific prior written permission.
     24  *
     25  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     28  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     29  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     30  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     31  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     34  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     35  * SUCH DAMAGE.
     36  *
     37  *
     38  * File: am-utils/libamu/misc_rpc.c
     39  *
     40  */
     41 
     42 /*
     43  * Additions to Sun RPC.
     44  */
     45 
     46 #ifdef HAVE_CONFIG_H
     47 # include <config.h>
     48 #endif /* HAVE_CONFIG_H */
     49 #include <am_defs.h>
     50 #include <amu.h>
     51 
     52 /*
     53  * Some systems renamed _seterr_reply to __seterr_reply (with two
     54  * leading underscores)
     55  */
     56 #if !defined(HAVE__SETERR_REPLY) && defined(HAVE___SETERR_REPLY)
     57 # define _seterr_reply	__seterr_reply
     58 #endif /* !defined(HAVE__SETERR_REPLY) && defined(HAVE___SETERR_REPLY) */
     59 
     60 
     61 void
     62 rpc_msg_init(struct rpc_msg *mp, u_long prog, u_long vers, u_long proc)
     63 {
     64   /*
     65    * Initialize the message
     66    */
     67   memset((voidp) mp, 0, sizeof(*mp));
     68   mp->rm_xid = 0;
     69   mp->rm_direction = CALL;
     70   mp->rm_call.cb_rpcvers = RPC_MSG_VERSION;
     71   mp->rm_call.cb_prog = prog;
     72   mp->rm_call.cb_vers = vers;
     73   mp->rm_call.cb_proc = proc;
     74 }
     75 
     76 
     77 /*
     78  * Field reply to call to mountd
     79  */
     80 int
     81 pickup_rpc_reply(voidp pkt, int len, voidp where, XDRPROC_T_TYPE where_xdr)
     82 {
     83   XDR reply_xdr;
     84   int ok;
     85   struct rpc_err err;
     86   struct rpc_msg reply_msg;
     87   int error = 0;
     88 
     89   /* memset((voidp) &err, 0, sizeof(err)); */
     90   memset((voidp) &reply_msg, 0, sizeof(reply_msg));
     91   memset((voidp) &reply_xdr, 0, sizeof(reply_xdr));
     92 
     93   reply_msg.acpted_rply.ar_results.where = where;
     94   reply_msg.acpted_rply.ar_results.proc = where_xdr;
     95 
     96   xdrmem_create(&reply_xdr, pkt, len, XDR_DECODE);
     97 
     98   ok = xdr_replymsg(&reply_xdr, &reply_msg);
     99   if (!ok) {
    100     error = EIO;
    101     goto drop;
    102   }
    103   _seterr_reply(&reply_msg, &err);
    104   if (err.re_status != RPC_SUCCESS) {
    105     error = EIO;
    106     goto drop;
    107   }
    108 
    109 drop:
    110   if (reply_msg.rm_reply.rp_stat == MSG_ACCEPTED &&
    111       reply_msg.acpted_rply.ar_verf.oa_base) {
    112     reply_xdr.x_op = XDR_FREE;
    113     (void) xdr_opaque_auth(&reply_xdr,
    114 			   &reply_msg.acpted_rply.ar_verf);
    115   }
    116   xdr_destroy(&reply_xdr);
    117 
    118   return error;
    119 }
    120 
    121 
    122 int
    123 make_rpc_packet(char *buf, int buflen, u_long proc, struct rpc_msg *mp, voidp arg, XDRPROC_T_TYPE arg_xdr, AUTH *auth)
    124 {
    125   XDR msg_xdr;
    126   int len;
    127   /*
    128    * Never cast pointers between different integer types, it breaks badly
    129    * on big-endian platforms if those types have different sizes.
    130    *
    131    * Cast to a local variable instead, and use that variable's address.
    132    */
    133   enum_t local_proc = (enum_t) proc;
    134 
    135   xdrmem_create(&msg_xdr, buf, buflen, XDR_ENCODE);
    136 
    137   /*
    138    * Basic protocol header
    139    */
    140   if (!xdr_callhdr(&msg_xdr, mp))
    141     return -EIO;
    142 
    143   /*
    144    * Called procedure number
    145    */
    146   if (!xdr_enum(&msg_xdr, &local_proc))
    147     return -EIO;
    148 
    149   /*
    150    * Authorization
    151    */
    152   if (!AUTH_MARSHALL(auth, &msg_xdr))
    153     return -EIO;
    154 
    155   /*
    156    * Arguments
    157    */
    158   if (!(*arg_xdr) (&msg_xdr, arg))
    159     return -EIO;
    160 
    161   /*
    162    * Determine length
    163    */
    164   len = xdr_getpos(&msg_xdr);
    165 
    166   /*
    167    * Throw away xdr
    168    */
    169   xdr_destroy(&msg_xdr);
    170 
    171   return len;
    172 }
    173 
    174 
    175 /* get uid/gid from RPC credentials */
    176 int
    177 getcreds(struct svc_req *rp, uid_t *u, gid_t *g, SVCXPRT *nfsxprt)
    178 {
    179   struct authunix_parms *aup = (struct authunix_parms *) NULL;
    180 #ifdef HAVE_RPC_AUTH_DES_H
    181   struct authdes_cred *adp;
    182 #endif /* HAVE_RPC_AUTH_DES_H */
    183 
    184   switch (rp->rq_cred.oa_flavor) {
    185 
    186   case AUTH_UNIX:
    187     aup = (struct authunix_parms *) rp->rq_clntcred;
    188     *u = aup->aup_uid;
    189     *g = aup->aup_gid;
    190     break;
    191 
    192 #ifdef HAVE_RPC_AUTH_DES_H
    193   case AUTH_DES:
    194     adp = (struct authdes_cred *) rp->rq_clntcred;
    195     *g = INVALIDID;		/* some unknown group id */
    196     if (sscanf(adp->adc_fullname.name, "unix.%lu@", (u_long *) u) == 1)
    197         break;
    198     /* fall through */
    199 #endif /* HAVE_RPC_AUTH_DES_H */
    200 
    201   default:
    202     *u = *g = INVALIDID;	/* just in case */
    203     svcerr_weakauth(nfsxprt);
    204     return -1;
    205   }
    206 
    207   return 0;			/* everything is ok */
    208 }
    209