Remove contrib/netbsd-tests/fs/nfs/nfsservice/rpcbind

This should have been pruned in r305358

MFC after:	3 days
Sponsored by:	Dell EMC Isilon
This commit is contained in:
Enji Cooper 2017-01-14 06:16:57 +00:00
parent dcdb30d8f8
commit 792bbaba98
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=312122
11 changed files with 0 additions and 4519 deletions

View File

@ -1,231 +0,0 @@
/* $NetBSD: check_bound.c,v 1.1 2010/07/26 15:53:00 pooka Exp $ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
* media and as a part of the software program in whole or part. Users
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
/*
* Copyright (c) 1986 - 1991 by Sun Microsystems, Inc.
*/
/* #ident "@(#)check_bound.c 1.15 93/07/05 SMI" */
#if 0
#ifndef lint
static char sccsid[] = "@(#)check_bound.c 1.11 89/04/21 Copyr 1989 Sun Micro";
#endif
#endif
/*
* check_bound.c
* Checks to see whether the program is still bound to the
* claimed address and returns the univeral merged address
*
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <rpc/rpc.h>
#include <stdio.h>
#include <netconfig.h>
#include <syslog.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <rump/rump.h>
#include <rump/rump_syscalls.h>
#include "rpcbind.h"
struct fdlist {
int fd;
struct netconfig *nconf;
struct fdlist *next;
int check_binding;
};
static struct fdlist *fdhead; /* Link list of the check fd's */
static struct fdlist *fdtail;
static const char emptystring[] = "";
static bool_t check_bound(struct fdlist *, const char *uaddr);
/*
* Returns 1 if the given address is bound for the given addr & transport
* For all error cases, we assume that the address is bound
* Returns 0 for success.
*/
static bool_t
check_bound(struct fdlist *fdl, const char *uaddr)
{
int fd;
struct netbuf *na;
int ans;
if (fdl->check_binding == FALSE)
return (TRUE);
na = uaddr2taddr(fdl->nconf, uaddr);
if (!na)
return (TRUE); /* punt, should never happen */
fd = __rpc_nconf2fd(fdl->nconf);
if (fd < 0) {
free(na);
return (TRUE);
}
ans = bind(fd, (struct sockaddr *)na->buf, na->len);
rump_sys_close(fd);
free(na);
return (ans == 0 ? FALSE : TRUE);
}
int
add_bndlist(struct netconfig *nconf, struct netbuf *baddr)
{
struct fdlist *fdl;
struct netconfig *newnconf;
newnconf = getnetconfigent(nconf->nc_netid);
if (newnconf == NULL)
return (-1);
fdl = (struct fdlist *)malloc((u_int)sizeof (struct fdlist));
if (fdl == NULL) {
freenetconfigent(newnconf);
syslog(LOG_ERR, "no memory!");
return (-1);
}
fdl->nconf = newnconf;
fdl->next = NULL;
if (fdhead == NULL) {
fdhead = fdl;
fdtail = fdl;
} else {
fdtail->next = fdl;
fdtail = fdl;
}
/* XXX no bound checking for now */
fdl->check_binding = FALSE;
return 0;
}
bool_t
is_bound(const char *netid, const char *uaddr)
{
struct fdlist *fdl;
for (fdl = fdhead; fdl; fdl = fdl->next)
if (strcmp(fdl->nconf->nc_netid, netid) == 0)
break;
if (fdl == NULL)
return (TRUE);
return (check_bound(fdl, uaddr));
}
/*
* Returns NULL if there was some system error.
* Returns "" if the address was not bound, i.e the server crashed.
* Returns the merged address otherwise.
*/
char *
mergeaddr(SVCXPRT *xprt, char *netid, char *uaddr, char *saddr)
{
struct fdlist *fdl;
char *c_uaddr, *s_uaddr, *m_uaddr, *allocated_uaddr = NULL;
for (fdl = fdhead; fdl; fdl = fdl->next)
if (strcmp(fdl->nconf->nc_netid, netid) == 0)
break;
if (fdl == NULL)
return (NULL);
if (check_bound(fdl, uaddr) == FALSE)
/* that server died */
return strdup(emptystring);
/*
* If saddr is not NULL, the remote client may have included the
* address by which it contacted us. Use that for the "client" uaddr,
* otherwise use the info from the SVCXPRT.
*/
if (saddr != NULL) {
c_uaddr = saddr;
} else {
c_uaddr = taddr2uaddr(fdl->nconf, svc_getrpccaller(xprt));
if (c_uaddr == NULL) {
syslog(LOG_ERR, "taddr2uaddr failed for %s",
fdl->nconf->nc_netid);
return (NULL);
}
allocated_uaddr = c_uaddr;
}
#ifdef RPCBIND_DEBUG
if (debugging) {
if (saddr == NULL) {
fprintf(stderr, "mergeaddr: client uaddr = %s\n",
c_uaddr);
} else {
fprintf(stderr, "mergeaddr: contact uaddr = %s\n",
c_uaddr);
}
}
#endif
s_uaddr = uaddr;
/*
* This is all we should need for IP 4 and 6
*/
m_uaddr = addrmerge(svc_getrpccaller(xprt), s_uaddr, c_uaddr, netid);
#ifdef RPCBIND_DEBUG
if (debugging)
fprintf(stderr, "mergeaddr: uaddr = %s, merged uaddr = %s\n",
uaddr, m_uaddr);
#endif
if (allocated_uaddr != NULL)
free(allocated_uaddr);
return (m_uaddr);
}
/*
* Returns a netconf structure from its internal list. This
* structure should not be freed.
*/
struct netconfig *
rpcbind_get_conf(const char *netid)
{
struct fdlist *fdl;
for (fdl = fdhead; fdl; fdl = fdl->next)
if (strcmp(fdl->nconf->nc_netid, netid) == 0)
break;
if (fdl == NULL)
return (NULL);
return (fdl->nconf);
}

View File

@ -1,366 +0,0 @@
/* $NetBSD: pmap_svc.c,v 1.2 2013/10/19 17:45:00 christos Exp $ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
* media and as a part of the software program in whole or part. Users
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
/*
* Copyright (c) 1984 - 1991 by Sun Microsystems, Inc.
*/
/* #ident "@(#)pmap_svc.c 1.14 93/07/05 SMI" */
#if 0
#ifndef lint
static char sccsid[] = "@(#)pmap_svc.c 1.23 89/04/05 Copyr 1984 Sun Micro";
#endif
#endif
/*
* pmap_svc.c
* The server procedure for the version 2 portmapper.
* All the portmapper related interface from the portmap side.
*/
#ifdef PORTMAP
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <rpc/rpc.h>
#include <rpc/pmap_prot.h>
#include <rpc/rpcb_prot.h>
#ifdef RPCBIND_DEBUG
#include <stdlib.h>
#endif
#include "rpcbind.h"
static struct pmaplist *find_service_pmap(rpcprog_t, rpcvers_t, rpcprot_t);
static bool_t pmapproc_change(struct svc_req *, SVCXPRT *, u_long);
static bool_t pmapproc_getport(struct svc_req *, SVCXPRT *);
static bool_t pmapproc_dump(struct svc_req *, SVCXPRT *);
/*
* Called for all the version 2 inquiries.
*/
void
pmap_service(struct svc_req *rqstp, SVCXPRT *xprt)
{
rpcbs_procinfo(RPCBVERS_2_STAT, rqstp->rq_proc);
switch (rqstp->rq_proc) {
case PMAPPROC_NULL:
/*
* Null proc call
*/
#ifdef RPCBIND_DEBUG
if (debugging)
fprintf(stderr, "PMAPPROC_NULL\n");
#endif
check_access(xprt, rqstp->rq_proc, NULL, PMAPVERS);
if ((!svc_sendreply(xprt, (xdrproc_t) xdr_void, NULL)) &&
debugging) {
if (doabort) {
rpcbind_abort();
}
}
break;
case PMAPPROC_SET:
/*
* Set a program, version to port mapping
*/
pmapproc_change(rqstp, xprt, rqstp->rq_proc);
break;
case PMAPPROC_UNSET:
/*
* Remove a program, version to port mapping.
*/
pmapproc_change(rqstp, xprt, rqstp->rq_proc);
break;
case PMAPPROC_GETPORT:
/*
* Lookup the mapping for a program, version and return its
* port number.
*/
pmapproc_getport(rqstp, xprt);
break;
case PMAPPROC_DUMP:
/*
* Return the current set of mapped program, version
*/
#ifdef RPCBIND_DEBUG
if (debugging)
fprintf(stderr, "PMAPPROC_DUMP\n");
#endif
pmapproc_dump(rqstp, xprt);
break;
case PMAPPROC_CALLIT:
/*
* Calls a procedure on the local machine. If the requested
* procedure is not registered this procedure does not return
* error information!!
* This procedure is only supported on rpc/udp and calls via
* rpc/udp. It passes null authentication parameters.
*/
rpcbproc_callit_com(rqstp, xprt, PMAPPROC_CALLIT, PMAPVERS);
break;
default:
svcerr_noproc(xprt);
break;
}
}
/*
* returns the item with the given program, version number. If that version
* number is not found, it returns the item with that program number, so that
* the port number is now returned to the caller. The caller when makes a
* call to this program, version number, the call will fail and it will
* return with PROGVERS_MISMATCH. The user can then determine the highest
* and the lowest version number for this program using clnt_geterr() and
* use those program version numbers.
*/
static struct pmaplist *
find_service_pmap(rpcprog_t prog, rpcvers_t vers, rpcprot_t prot)
{
register struct pmaplist *hit = NULL;
register struct pmaplist *pml;
for (pml = list_pml; pml != NULL; pml = pml->pml_next) {
if ((pml->pml_map.pm_prog != prog) ||
(pml->pml_map.pm_prot != prot))
continue;
hit = pml;
if (pml->pml_map.pm_vers == vers)
break;
}
return (hit);
}
static bool_t
pmapproc_change(struct svc_req *rqstp, SVCXPRT *xprt, unsigned long op)
{
struct pmap reg;
RPCB rpcbreg;
long ans;
struct sockcred *sc;
char uidbuf[32];
#ifdef RPCBIND_DEBUG
if (debugging)
fprintf(stderr, "%s request for (%lu, %lu) : ",
op == PMAPPROC_SET ? "PMAP_SET" : "PMAP_UNSET",
reg.pm_prog, reg.pm_vers);
#endif
if (!svc_getargs(xprt, (xdrproc_t) xdr_pmap, (char *)&reg)) {
svcerr_decode(xprt);
return (FALSE);
}
if (!check_access(xprt, op, &reg, PMAPVERS)) {
svcerr_weakauth(xprt);
return FALSE;
}
(void)svc_getcaller(xprt);
sc = __svc_getcallercreds(xprt);
/*
* Can't use getpwnam here. We might end up calling ourselves
* and looping.
*/
if (sc == NULL)
rpcbreg.r_owner = __UNCONST(rpcbind_unknown);
else if (sc->sc_uid == 0)
rpcbreg.r_owner = __UNCONST(rpcbind_superuser);
else {
/* r_owner will be strdup-ed later */
snprintf(uidbuf, sizeof uidbuf, "%d", sc->sc_uid);
rpcbreg.r_owner = uidbuf;
}
rpcbreg.r_prog = reg.pm_prog;
rpcbreg.r_vers = reg.pm_vers;
if (op == PMAPPROC_SET) {
char buf[32];
snprintf(buf, sizeof(buf), "0.0.0.0.%d.%d",
(int)((reg.pm_port >> 8) & 0xff),
(int)(reg.pm_port & 0xff));
rpcbreg.r_addr = buf;
if (reg.pm_prot == IPPROTO_UDP) {
rpcbreg.r_netid = __UNCONST(udptrans);
} else if (reg.pm_prot == IPPROTO_TCP) {
rpcbreg.r_netid = __UNCONST(tcptrans);
} else {
ans = FALSE;
goto done_change;
}
ans = map_set(&rpcbreg, rpcbreg.r_owner);
} else if (op == PMAPPROC_UNSET) {
bool_t ans1, ans2;
rpcbreg.r_addr = NULL;
rpcbreg.r_netid = __UNCONST(tcptrans);
ans1 = map_unset(&rpcbreg, rpcbreg.r_owner);
rpcbreg.r_netid = __UNCONST(udptrans);
ans2 = map_unset(&rpcbreg, rpcbreg.r_owner);
ans = ans1 || ans2;
} else {
ans = FALSE;
}
done_change:
if ((!svc_sendreply(xprt, (xdrproc_t) xdr_long, (caddr_t) &ans)) &&
debugging) {
fprintf(stderr, "portmap: svc_sendreply\n");
if (doabort) {
rpcbind_abort();
}
}
#ifdef RPCBIND_DEBUG
if (debugging)
fprintf(stderr, "%s\n", ans == TRUE ? "succeeded" : "failed");
#endif
if (op == PMAPPROC_SET)
rpcbs_set(RPCBVERS_2_STAT, ans);
else
rpcbs_unset(RPCBVERS_2_STAT, ans);
return (TRUE);
}
/* ARGSUSED */
static bool_t
pmapproc_getport(struct svc_req *rqstp, SVCXPRT *xprt)
{
struct pmap reg;
long lport;
int port = 0;
struct pmaplist *fnd;
#ifdef RPCBIND_DEBUG
char *uaddr;
#endif
if (!svc_getargs(xprt, (xdrproc_t) xdr_pmap, (char *)&reg)) {
svcerr_decode(xprt);
return (FALSE);
}
if (!check_access(xprt, PMAPPROC_GETPORT, &reg, PMAPVERS)) {
svcerr_weakauth(xprt);
return FALSE;
}
#ifdef RPCBIND_DEBUG
if (debugging) {
uaddr = taddr2uaddr(rpcbind_get_conf(xprt->xp_netid),
svc_getrpccaller(xprt));
fprintf(stderr, "PMAP_GETPORT req for (%lu, %lu, %s) from %s :",
reg.pm_prog, reg.pm_vers,
reg.pm_prot == IPPROTO_UDP ? "udp" : "tcp", uaddr);
free(uaddr);
}
#endif
fnd = find_service_pmap(reg.pm_prog, reg.pm_vers, reg.pm_prot);
if (fnd) {
char serveuaddr[32];
int h1, h2, h3, h4, p1, p2;
const char *netid, *ua;
if (reg.pm_prot == IPPROTO_UDP) {
ua = udp_uaddr;
netid = udptrans;
} else {
ua = tcp_uaddr; /* To get the len */
netid = tcptrans;
}
if (ua == NULL) {
goto sendreply;
}
if (sscanf(ua, "%d.%d.%d.%d.%d.%d", &h1, &h2, &h3,
&h4, &p1, &p2) == 6) {
p1 = (fnd->pml_map.pm_port >> 8) & 0xff;
p2 = (fnd->pml_map.pm_port) & 0xff;
snprintf(serveuaddr, sizeof(serveuaddr),
"%d.%d.%d.%d.%d.%d", h1, h2, h3, h4, p1, p2);
if (is_bound(netid, serveuaddr)) {
port = fnd->pml_map.pm_port;
} else { /* this service is dead; delete it */
delete_prog(reg.pm_prog);
}
}
}
sendreply:
lport = port;
if ((!svc_sendreply(xprt, (xdrproc_t) xdr_long, (caddr_t)&lport)) &&
debugging) {
(void) fprintf(stderr, "portmap: svc_sendreply\n");
if (doabort) {
rpcbind_abort();
}
}
#ifdef RPCBIND_DEBUG
if (debugging)
fprintf(stderr, "port = %d\n", port);
#endif
rpcbs_getaddr(RPCBVERS_2_STAT, reg.pm_prog, reg.pm_vers,
reg.pm_prot == IPPROTO_UDP ? udptrans : tcptrans,
port ? udptrans : "");
return (TRUE);
}
/* ARGSUSED */
static bool_t
pmapproc_dump(struct svc_req *rqstp, SVCXPRT *xprt)
{
if (!svc_getargs(xprt, (xdrproc_t)xdr_void, NULL)) {
svcerr_decode(xprt);
return (FALSE);
}
if (!check_access(xprt, PMAPPROC_DUMP, NULL, PMAPVERS)) {
svcerr_weakauth(xprt);
return FALSE;
}
if ((!svc_sendreply(xprt, (xdrproc_t) xdr_pmaplist_ptr,
(caddr_t)&list_pml)) && debugging) {
if (debugging)
(void) fprintf(stderr, "portmap: svc_sendreply\n");
if (doabort) {
rpcbind_abort();
}
}
return (TRUE);
}
#endif /* PORTMAP */

View File

@ -1,206 +0,0 @@
/* $NetBSD: rpcb_stat.c,v 1.1 2010/07/26 15:53:00 pooka Exp $ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
* media and as a part of the software program in whole or part. Users
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
/* #pragma ident "@(#)rpcb_stat.c 1.7 94/04/25 SMI" */
/*
* rpcb_stat.c
* Allows for gathering of statistics
*
* Copyright (c) 1990 by Sun Microsystems, Inc.
*/
#include <stdio.h>
#include <netconfig.h>
#include <rpc/rpc.h>
#include <rpc/rpcb_prot.h>
#include <sys/stat.h>
#ifdef PORTMAP
#include <rpc/pmap_prot.h>
#endif
#include <stdlib.h>
#include <string.h>
#include "rpcbind.h"
static rpcb_stat_byvers inf;
void
rpcbs_init(void)
{
}
void
rpcbs_procinfo(rpcvers_t rtype, rpcproc_t proc)
{
switch (rtype + 2) {
#ifdef PORTMAP
case PMAPVERS: /* version 2 */
if (proc > rpcb_highproc_2)
return;
break;
#endif
case RPCBVERS: /* version 3 */
if (proc > rpcb_highproc_3)
return;
break;
case RPCBVERS4: /* version 4 */
if (proc > rpcb_highproc_4)
return;
break;
default: return;
}
inf[rtype].info[proc]++;
return;
}
void
rpcbs_set(rpcvers_t rtype, bool_t success)
{
if ((rtype >= RPCBVERS_STAT) || (success == FALSE))
return;
inf[rtype].setinfo++;
return;
}
void
rpcbs_unset(rpcvers_t rtype, bool_t success)
{
if ((rtype >= RPCBVERS_STAT) || (success == FALSE))
return;
inf[rtype].unsetinfo++;
return;
}
void
rpcbs_getaddr(rpcvers_t rtype, rpcprog_t prog, rpcvers_t vers,
const char *netid, const char *uaddr)
{
rpcbs_addrlist *al;
struct netconfig *nconf;
if (rtype >= RPCBVERS_STAT)
return;
for (al = inf[rtype].addrinfo; al; al = al->next) {
if(al->netid == NULL)
return;
if ((al->prog == prog) && (al->vers == vers) &&
(strcmp(al->netid, netid) == 0)) {
if ((uaddr == NULL) || (uaddr[0] == 0))
al->failure++;
else
al->success++;
return;
}
}
nconf = rpcbind_get_conf(netid);
if (nconf == NULL) {
return;
}
al = (rpcbs_addrlist *) malloc(sizeof (rpcbs_addrlist));
if (al == NULL) {
return;
}
al->prog = prog;
al->vers = vers;
al->netid = nconf->nc_netid;
if ((uaddr == NULL) || (uaddr[0] == 0)) {
al->failure = 1;
al->success = 0;
} else {
al->failure = 0;
al->success = 1;
}
al->next = inf[rtype].addrinfo;
inf[rtype].addrinfo = al;
}
void
rpcbs_rmtcall(rpcvers_t rtype, rpcproc_t rpcbproc, rpcprog_t prog,
rpcvers_t vers, rpcproc_t proc, char *netid, rpcblist_ptr rbl)
{
rpcbs_rmtcalllist *rl;
struct netconfig *nconf;
if (rtype >= RPCBVERS_STAT)
return;
for (rl = inf[rtype].rmtinfo; rl; rl = rl->next) {
if(rl->netid == NULL)
return;
if ((rl->prog == prog) && (rl->vers == vers) &&
(rl->proc == proc) &&
(strcmp(rl->netid, netid) == 0)) {
if ((rbl == NULL) ||
(rbl->rpcb_map.r_vers != vers))
rl->failure++;
else
rl->success++;
if (rpcbproc == RPCBPROC_INDIRECT)
rl->indirect++;
return;
}
}
nconf = rpcbind_get_conf(netid);
if (nconf == NULL) {
return;
}
rl = (rpcbs_rmtcalllist *) malloc(sizeof (rpcbs_rmtcalllist));
if (rl == NULL) {
return;
}
rl->prog = prog;
rl->vers = vers;
rl->proc = proc;
rl->netid = nconf->nc_netid;
if ((rbl == NULL) ||
(rbl->rpcb_map.r_vers != vers)) {
rl->failure = 1;
rl->success = 0;
} else {
rl->failure = 0;
rl->success = 1;
}
rl->indirect = 1;
rl->next = inf[rtype].rmtinfo;
inf[rtype].rmtinfo = rl;
return;
}
/*
*/
void *
rpcbproc_getstat(void *arg, struct svc_req *req, SVCXPRT *xprt,
rpcvers_t versnum)
{
return (void *)&inf;
}

View File

@ -1,232 +0,0 @@
/* $NetBSD: rpcb_svc.c,v 1.2 2011/09/16 16:13:18 plunky Exp $ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
* media and as a part of the software program in whole or part. Users
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
/*
* Copyright (c) 1986 - 1991 by Sun Microsystems, Inc.
*/
/* #ident "@(#)rpcb_svc.c 1.16 93/07/05 SMI" */
/*
* rpcb_svc.c
* The server procedure for the version 3 rpcbind (TLI).
*
* It maintains a separate list of all the registered services with the
* version 3 of rpcbind.
*/
#include <sys/types.h>
#include <rpc/rpc.h>
#include <rpc/rpcb_prot.h>
#include <netconfig.h>
#include <syslog.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "rpcbind.h"
static void *rpcbproc_getaddr_3_local(void *, struct svc_req *, SVCXPRT *,
rpcvers_t);
static void *rpcbproc_dump_3_local(void *, struct svc_req *, SVCXPRT *,
rpcvers_t);
/*
* Called by svc_getreqset. There is a separate server handle for
* every transport that it waits on.
*/
void
rpcb_service_3(struct svc_req *rqstp, SVCXPRT *transp)
{
union {
RPCB rpcbproc_set_3_arg;
RPCB rpcbproc_unset_3_arg;
RPCB rpcbproc_getaddr_3_local_arg;
struct rpcb_rmtcallargs rpcbproc_callit_3_arg;
char *rpcbproc_uaddr2taddr_3_arg;
struct netbuf rpcbproc_taddr2uaddr_3_arg;
} argument;
char *result;
xdrproc_t xdr_argument, xdr_result;
void *(*local)(void *, struct svc_req *, SVCXPRT *, rpcvers_t);
rpcbs_procinfo(RPCBVERS_3_STAT, rqstp->rq_proc);
switch (rqstp->rq_proc) {
case NULLPROC:
/*
* Null proc call
*/
#ifdef RPCBIND_DEBUG
if (debugging)
fprintf(stderr, "RPCBPROC_NULL\n");
#endif
/* This call just logs, no actual checks */
check_access(transp, rqstp->rq_proc, NULL, RPCBVERS);
(void) svc_sendreply(transp, (xdrproc_t)xdr_void, NULL);
return;
case RPCBPROC_SET:
xdr_argument = (xdrproc_t )xdr_rpcb;
xdr_result = (xdrproc_t )xdr_bool;
local = rpcbproc_set_com;
break;
case RPCBPROC_UNSET:
xdr_argument = (xdrproc_t)xdr_rpcb;
xdr_result = (xdrproc_t)xdr_bool;
local = rpcbproc_unset_com;
break;
case RPCBPROC_GETADDR:
xdr_argument = (xdrproc_t)xdr_rpcb;
xdr_result = (xdrproc_t)xdr_wrapstring;
local = rpcbproc_getaddr_3_local;
break;
case RPCBPROC_DUMP:
#ifdef RPCBIND_DEBUG
if (debugging)
fprintf(stderr, "RPCBPROC_DUMP\n");
#endif
xdr_argument = (xdrproc_t)xdr_void;
xdr_result = (xdrproc_t)xdr_rpcblist_ptr;
local = rpcbproc_dump_3_local;
break;
case RPCBPROC_CALLIT:
rpcbproc_callit_com(rqstp, transp, rqstp->rq_proc, RPCBVERS);
return;
case RPCBPROC_GETTIME:
#ifdef RPCBIND_DEBUG
if (debugging)
fprintf(stderr, "RPCBPROC_GETTIME\n");
#endif
xdr_argument = (xdrproc_t)xdr_void;
xdr_result = (xdrproc_t)xdr_u_long;
local = rpcbproc_gettime_com;
break;
case RPCBPROC_UADDR2TADDR:
#ifdef RPCBIND_DEBUG
if (debugging)
fprintf(stderr, "RPCBPROC_UADDR2TADDR\n");
#endif
xdr_argument = (xdrproc_t)xdr_wrapstring;
xdr_result = (xdrproc_t)xdr_netbuf;
local = rpcbproc_uaddr2taddr_com;
break;
case RPCBPROC_TADDR2UADDR:
#ifdef RPCBIND_DEBUG
if (debugging)
fprintf(stderr, "RPCBPROC_TADDR2UADDR\n");
#endif
xdr_argument = (xdrproc_t)xdr_netbuf;
xdr_result = (xdrproc_t)xdr_wrapstring;
local = rpcbproc_taddr2uaddr_com;
break;
default:
svcerr_noproc(transp);
return;
}
(void) memset((char *)&argument, 0, sizeof (argument));
if (!svc_getargs(transp, (xdrproc_t) xdr_argument,
(char *) &argument)) {
svcerr_decode(transp);
if (debugging)
(void) fprintf(stderr, "rpcbind: could not decode\n");
return;
}
if (!check_access(transp, rqstp->rq_proc, &argument, RPCBVERS)) {
svcerr_weakauth(transp);
goto done;
}
result = (*local)(&argument, rqstp, transp, RPCBVERS);
if (result != NULL && !svc_sendreply(transp, (xdrproc_t)xdr_result,
result)) {
svcerr_systemerr(transp);
if (debugging) {
(void) fprintf(stderr, "rpcbind: svc_sendreply\n");
if (doabort) {
rpcbind_abort();
}
}
}
done:
if (!svc_freeargs(transp, (xdrproc_t)xdr_argument, (char *)
&argument)) {
if (debugging) {
(void) fprintf(stderr, "unable to free arguments\n");
if (doabort) {
rpcbind_abort();
}
}
}
}
/*
* Lookup the mapping for a program, version and return its
* address. Assuming that the caller wants the address of the
* server running on the transport on which the request came.
*
* We also try to resolve the universal address in terms of
* address of the caller.
*/
/* ARGSUSED */
static void *
rpcbproc_getaddr_3_local(void *arg, struct svc_req *rqstp, SVCXPRT *transp,
rpcvers_t versnum)
{
RPCB *regp = (RPCB *)arg;
#ifdef RPCBIND_DEBUG
if (debugging) {
char *uaddr;
uaddr = taddr2uaddr(rpcbind_get_conf(transp->xp_netid),
svc_getrpccaller(transp));
fprintf(stderr, "RPCB_GETADDR req for (%lu, %lu, %s) from %s: ",
(unsigned long)regp->r_prog, (unsigned long)regp->r_vers,
regp->r_netid, uaddr);
free(uaddr);
}
#endif
return (rpcbproc_getaddr_com(regp, rqstp, transp, RPCBVERS,
RPCB_ALLVERS));
}
/* ARGSUSED */
static void *
rpcbproc_dump_3_local(void *arg, struct svc_req *rqstp, SVCXPRT *transp,
rpcvers_t versnum)
{
return ((void *)&list_rbl);
}

View File

@ -1,455 +0,0 @@
/* $NetBSD: rpcb_svc_4.c,v 1.2 2011/09/16 16:13:18 plunky Exp $ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
* media and as a part of the software program in whole or part. Users
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
/*
* Copyright (c) 1986 - 1991 by Sun Microsystems, Inc.
*/
/* #ident "@(#)rpcb_svc_4.c 1.8 93/07/05 SMI" */
/*
* rpcb_svc_4.c
* The server procedure for the version 4 rpcbind.
*
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <rpc/rpc.h>
#include <stdio.h>
#include <unistd.h>
#include <netconfig.h>
#include <syslog.h>
#include <string.h>
#include <stdlib.h>
#include "rpcbind.h"
static void *rpcbproc_getaddr_4_local(void *, struct svc_req *, SVCXPRT *,
rpcvers_t);
static void *rpcbproc_getversaddr_4_local(void *, struct svc_req *, SVCXPRT *,
rpcvers_t);
static void *rpcbproc_getaddrlist_4_local(void *, struct svc_req *, SVCXPRT *,
rpcvers_t);
static void free_rpcb_entry_list(rpcb_entry_list_ptr *);
static void *rpcbproc_dump_4_local(void *, struct svc_req *, SVCXPRT *,
rpcvers_t);
/*
* Called by svc_getreqset. There is a separate server handle for
* every transport that it waits on.
*/
void
rpcb_service_4(struct svc_req *rqstp, SVCXPRT *transp)
{
union {
rpcb rpcbproc_set_4_arg;
rpcb rpcbproc_unset_4_arg;
rpcb rpcbproc_getaddr_4_local_arg;
char *rpcbproc_uaddr2taddr_4_arg;
struct netbuf rpcbproc_taddr2uaddr_4_arg;
} argument;
char *result;
xdrproc_t xdr_argument, xdr_result;
void *(*local)(void *, struct svc_req *, SVCXPRT *, rpcvers_t);
rpcbs_procinfo(RPCBVERS_4_STAT, rqstp->rq_proc);
switch (rqstp->rq_proc) {
case NULLPROC:
/*
* Null proc call
*/
#ifdef RPCBIND_DEBUG
if (debugging)
fprintf(stderr, "RPCBPROC_NULL\n");
#endif
check_access(transp, rqstp->rq_proc, NULL, RPCBVERS4);
(void) svc_sendreply(transp, (xdrproc_t) xdr_void, NULL);
return;
case RPCBPROC_SET:
/*
* Check to see whether the message came from
* loopback transports (for security reasons)
*/
xdr_argument = (xdrproc_t)xdr_rpcb;
xdr_result = (xdrproc_t)xdr_bool;
local = rpcbproc_set_com;
break;
case RPCBPROC_UNSET:
/*
* Check to see whether the message came from
* loopback transports (for security reasons)
*/
xdr_argument = (xdrproc_t)xdr_rpcb;
xdr_result = (xdrproc_t)xdr_bool;
local = rpcbproc_unset_com;
break;
case RPCBPROC_GETADDR:
xdr_argument = (xdrproc_t)xdr_rpcb;
xdr_result = (xdrproc_t)xdr_wrapstring;
local = rpcbproc_getaddr_4_local;
break;
case RPCBPROC_GETVERSADDR:
#ifdef RPCBIND_DEBUG
if (debugging)
fprintf(stderr, "RPCBPROC_GETVERSADDR\n");
#endif
xdr_argument = (xdrproc_t)xdr_rpcb;
xdr_result = (xdrproc_t)xdr_wrapstring;
local = rpcbproc_getversaddr_4_local;
break;
case RPCBPROC_DUMP:
#ifdef RPCBIND_DEBUG
if (debugging)
fprintf(stderr, "RPCBPROC_DUMP\n");
#endif
xdr_argument = (xdrproc_t)xdr_void;
xdr_result = (xdrproc_t)xdr_rpcblist_ptr;
local = rpcbproc_dump_4_local;
break;
case RPCBPROC_INDIRECT:
#ifdef RPCBIND_DEBUG
if (debugging)
fprintf(stderr, "RPCBPROC_INDIRECT\n");
#endif
rpcbproc_callit_com(rqstp, transp, rqstp->rq_proc, RPCBVERS4);
return;
/* case RPCBPROC_CALLIT: */
case RPCBPROC_BCAST:
#ifdef RPCBIND_DEBUG
if (debugging)
fprintf(stderr, "RPCBPROC_BCAST\n");
#endif
rpcbproc_callit_com(rqstp, transp, rqstp->rq_proc, RPCBVERS4);
return;
case RPCBPROC_GETTIME:
#ifdef RPCBIND_DEBUG
if (debugging)
fprintf(stderr, "RPCBPROC_GETTIME\n");
#endif
xdr_argument = (xdrproc_t)xdr_void;
xdr_result = (xdrproc_t)xdr_u_long;
local = rpcbproc_gettime_com;
break;
case RPCBPROC_UADDR2TADDR:
#ifdef RPCBIND_DEBUG
if (debugging)
fprintf(stderr, "RPCBPROC_UADDR2TADDR\n");
#endif
xdr_argument = (xdrproc_t)xdr_wrapstring;
xdr_result = (xdrproc_t)xdr_netbuf;
local = rpcbproc_uaddr2taddr_com;
break;
case RPCBPROC_TADDR2UADDR:
#ifdef RPCBIND_DEBUG
if (debugging)
fprintf(stderr, "RPCBPROC_TADDR2UADDR\n");
#endif
xdr_argument = (xdrproc_t)xdr_netbuf;
xdr_result = (xdrproc_t)xdr_wrapstring;
local = rpcbproc_taddr2uaddr_com;
break;
case RPCBPROC_GETADDRLIST:
#ifdef RPCBIND_DEBUG
if (debugging)
fprintf(stderr, "RPCBPROC_GETADDRLIST\n");
#endif
xdr_argument = (xdrproc_t)xdr_rpcb;
xdr_result = (xdrproc_t)xdr_rpcb_entry_list_ptr;
local = rpcbproc_getaddrlist_4_local;
break;
case RPCBPROC_GETSTAT:
#ifdef RPCBIND_DEBUG
if (debugging)
fprintf(stderr, "RPCBPROC_GETSTAT\n");
#endif
xdr_argument = (xdrproc_t)xdr_void;
xdr_result = (xdrproc_t)xdr_rpcb_stat_byvers;
local = rpcbproc_getstat;
break;
default:
svcerr_noproc(transp);
return;
}
memset((char *)&argument, 0, sizeof (argument));
if (!svc_getargs(transp, (xdrproc_t) xdr_argument,
(char *)&argument)) {
svcerr_decode(transp);
if (debugging)
(void) fprintf(stderr, "rpcbind: could not decode\n");
return;
}
if (!check_access(transp, rqstp->rq_proc, &argument, RPCBVERS4)) {
svcerr_weakauth(transp);
goto done;
}
result = (*local)(&argument, rqstp, transp, RPCBVERS4);
if (result != NULL && !svc_sendreply(transp, (xdrproc_t) xdr_result,
result)) {
svcerr_systemerr(transp);
if (debugging) {
(void) fprintf(stderr, "rpcbind: svc_sendreply\n");
if (doabort) {
rpcbind_abort();
}
}
}
done:
if (!svc_freeargs(transp, (xdrproc_t) xdr_argument,
(char *)&argument)) {
if (debugging) {
(void) fprintf(stderr, "unable to free arguments\n");
if (doabort) {
rpcbind_abort();
}
}
}
return;
}
/*
* Lookup the mapping for a program, version and return its
* address. Assuming that the caller wants the address of the
* server running on the transport on which the request came.
* Even if a service with a different version number is available,
* it will return that address. The client should check with an
* clnt_call to verify whether the service is the one that is desired.
* We also try to resolve the universal address in terms of
* address of the caller.
*/
/* ARGSUSED */
static void *
rpcbproc_getaddr_4_local(void *arg, struct svc_req *rqstp, SVCXPRT *transp,
rpcvers_t rpcbversnum)
{
RPCB *regp = (RPCB *)arg;
#ifdef RPCBIND_DEBUG
if (debugging) {
char *uaddr;
uaddr = taddr2uaddr(rpcbind_get_conf(transp->xp_netid),
svc_getrpccaller(transp));
fprintf(stderr, "RPCB_GETADDR req for (%lu, %lu, %s) from %s: ",
(unsigned long)regp->r_prog, (unsigned long)regp->r_vers,
regp->r_netid, uaddr);
free(uaddr);
}
#endif
return (rpcbproc_getaddr_com(regp, rqstp, transp, RPCBVERS4,
RPCB_ALLVERS));
}
/*
* Lookup the mapping for a program, version and return its
* address. Assuming that the caller wants the address of the
* server running on the transport on which the request came.
*
* We also try to resolve the universal address in terms of
* address of the caller.
*/
/* ARGSUSED */
static void *
rpcbproc_getversaddr_4_local(void *arg, struct svc_req *rqstp, SVCXPRT *transp,
rpcvers_t versnum)
{
RPCB *regp = (RPCB *)arg;
#ifdef RPCBIND_DEBUG
if (debugging) {
char *uaddr;
uaddr = taddr2uaddr(rpcbind_get_conf(transp->xp_netid),
svc_getrpccaller(transp));
fprintf(stderr, "RPCB_GETVERSADDR rqst for (%lu, %lu, %s)"
" from %s : ",
(unsigned long)regp->r_prog, (unsigned long)regp->r_vers,
regp->r_netid, uaddr);
free(uaddr);
}
#endif
return (rpcbproc_getaddr_com(regp, rqstp, transp, RPCBVERS4,
RPCB_ONEVERS));
}
/*
* Lookup the mapping for a program, version and return the
* addresses for all transports in the current transport family.
* We return a merged address.
*/
/* ARGSUSED */
static void *
rpcbproc_getaddrlist_4_local(void *arg, struct svc_req *rqstp, SVCXPRT *transp,
rpcvers_t versnum)
{
RPCB *regp = (RPCB *)arg;
static rpcb_entry_list_ptr rlist;
register rpcblist_ptr rbl;
rpcb_entry_list_ptr rp, tail = NULL;
rpcprog_t prog;
rpcvers_t vers;
rpcb_entry *a;
struct netconfig *nconf;
struct netconfig *reg_nconf;
char *saddr, *maddr = NULL;
free_rpcb_entry_list(&rlist);
prog = regp->r_prog;
vers = regp->r_vers;
reg_nconf = rpcbind_get_conf(transp->xp_netid);
if (reg_nconf == NULL)
return (NULL);
if (*(regp->r_addr) != '\0') {
saddr = regp->r_addr;
} else {
saddr = NULL;
}
#ifdef RPCBIND_DEBUG
if (debugging) {
fprintf(stderr, "r_addr: %s r_netid: %s nc_protofmly: %s\n",
regp->r_addr, regp->r_netid, reg_nconf->nc_protofmly);
}
#endif
for (rbl = list_rbl; rbl != NULL; rbl = rbl->rpcb_next) {
if ((rbl->rpcb_map.r_prog == prog) &&
(rbl->rpcb_map.r_vers == vers)) {
nconf = rpcbind_get_conf(rbl->rpcb_map.r_netid);
if (nconf == NULL)
goto fail;
if (strcmp(nconf->nc_protofmly, reg_nconf->nc_protofmly)
!= 0) {
continue; /* not same proto family */
}
#ifdef RPCBIND_DEBUG
if (debugging)
fprintf(stderr, "\tmerge with: %s\n", rbl->rpcb_map.r_addr);
#endif
if ((maddr = mergeaddr(transp, rbl->rpcb_map.r_netid,
rbl->rpcb_map.r_addr, saddr)) == NULL) {
#ifdef RPCBIND_DEBUG
if (debugging)
fprintf(stderr, " FAILED\n");
#endif
continue;
} else if (!maddr[0]) {
#ifdef RPCBIND_DEBUG
if (debugging)
fprintf(stderr, " SUCCEEDED, but port died - maddr: nullstring\n");
#endif
/* The server died. Unset this combination */
delete_prog(regp->r_prog);
free(maddr);
continue;
}
#ifdef RPCBIND_DEBUG
if (debugging)
fprintf(stderr, " SUCCEEDED maddr: %s\n", maddr);
#endif
/*
* Add it to rlist.
*/
rp = (rpcb_entry_list_ptr)
malloc((u_int)sizeof (rpcb_entry_list));
if (rp == NULL) {
free(maddr);
goto fail;
}
a = &rp->rpcb_entry_map;
a->r_maddr = maddr;
a->r_nc_netid = nconf->nc_netid;
a->r_nc_semantics = nconf->nc_semantics;
a->r_nc_protofmly = nconf->nc_protofmly;
a->r_nc_proto = nconf->nc_proto;
rp->rpcb_entry_next = NULL;
if (rlist == NULL) {
rlist = rp;
tail = rp;
} else if (tail) {
tail->rpcb_entry_next = rp;
tail = rp;
}
rp = NULL;
}
}
#ifdef RPCBIND_DEBUG
if (debugging) {
for (rp = rlist; rp; rp = rp->rpcb_entry_next) {
fprintf(stderr, "\t%s %s\n", rp->rpcb_entry_map.r_maddr,
rp->rpcb_entry_map.r_nc_proto);
}
}
#endif
/*
* XXX: getaddrlist info is also being stuffed into getaddr.
* Perhaps wrong, but better than it not getting counted at all.
*/
rpcbs_getaddr(RPCBVERS4 - 2, prog, vers, transp->xp_netid, maddr);
return (void *)&rlist;
fail: free_rpcb_entry_list(&rlist);
return (NULL);
}
/*
* Free only the allocated structure, rest is all a pointer to some
* other data somewhere else.
*/
static void
free_rpcb_entry_list(rpcb_entry_list_ptr *rlistp)
{
register rpcb_entry_list_ptr rbl, tmp;
for (rbl = *rlistp; rbl != NULL; ) {
tmp = rbl;
rbl = rbl->rpcb_entry_next;
free((char *)tmp->rpcb_entry_map.r_maddr);
free((char *)tmp);
}
*rlistp = NULL;
}
/* ARGSUSED */
static void *
rpcbproc_dump_4_local(void *arg, struct svc_req *req, SVCXPRT *xprt,
rpcvers_t versnum)
{
return ((void *)&list_rbl);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,127 +0,0 @@
.\" $NetBSD: rpcbind.8,v 1.1 2010/07/26 15:53:00 pooka Exp $
.\" @(#)rpcbind.1m 1.19 92/09/14 SMI; from SVr4
.\" Copyright 1989 AT&T
.\" Copyright 1991 Sun Microsystems, Inc.
.Dd October 19, 2008
.Dt RPCBIND 8
.Sh NAME
.Nm rpcbind
.Nd universal addresses to RPC program number mapper
.Sh SYNOPSIS
.Nm
.Op Fl dilLs
.Sh DESCRIPTION
.Nm
is a server that converts
.Tn RPC
program numbers into
universal addresses.
It must be running on the host to be able to make
.Tn RPC
calls
on a server on that machine.
.Pp
When an
.Tn RPC
service is started,
it tells
.Nm
the address at which it is listening,
and the
.Tn RPC
program numbers it is prepared to serve.
When a client wishes to make an
.Tn RPC
call to a given program number,
it first contacts
.Nm
on the server machine to determine
the address where
.Tn RPC
requests should be sent.
.Pp
.Nm
should be started before any other RPC service.
Normally, standard
.Tn RPC
servers are started by port monitors, so
.Nm
must be started before port monitors are invoked.
.Pp
When
.Nm
is started, it checks that certain name-to-address
translation-calls function correctly.
If they fail, the network configuration databases may be corrupt.
Since
.Tn RPC
services cannot function correctly in this situation,
.Nm
reports the condition and terminates.
.Pp
.Nm
can only be started by the super-user.
.Pp
Access control is provided by
.Pa /etc/hosts.allow
and
.Pa /etc/hosts.deny ,
as described in
.Xr hosts_access 5
with daemon name
.Nm .
.Sh OPTIONS
.Bl -tag -width Ds
.It Fl d
Run in debug mode.
In this mode,
.Nm
will not fork when it starts, will print additional information
during operation, and will abort on certain errors.
With this option, the name-to-address translation consistency
checks are shown in detail.
.It Fl i
.Dq insecure
mode.
Allows calls to SET and UNSET from any host.
Normally
.Nm
accepts these requests only from the loopback interface for security reasons.
This change is necessary for programs that were compiled with earlier
versions of the rpc library and do not make those requests using the
loopback interface.
.It Fl l
Turns on libwrap connection logging.
.It Fl s
Causes
.Nm
to change to the user daemon as soon as possible.
This causes
.Nm
to use non-privileged ports for outgoing connections, preventing non-privileged
clients from using
.Nm
to connect to services from a privileged port.
.It Fl L
Allow old-style local connections over the loopback interface.
Without this flag, local connections are only allowed over a local socket,
.Pa /var/run/rpcbind.sock
.El
.Sh NOTES
All RPC servers must be restarted if
.Nm
is restarted.
.Sh FILES
.Bl -tag -width "/var/run/rpcbind.sock" -compact
.It Pa /var/run/rpcbind.sock
.It Pa /etc/hosts.allow
explicit remote host access list.
.It Pa /etc/hosts.deny
explicit remote host denial of service list.
.El
.Sh SEE ALSO
.Xr rpcbind 3 ,
.Xr hosts_access 5 ,
.Xr hosts_options 5 ,
.Xr netconfig 5 ,
.Xr rpcinfo 8

View File

@ -1,613 +0,0 @@
/* $NetBSD: rpcbind.c,v 1.4 2013/10/19 17:45:00 christos Exp $ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
* media and as a part of the software program in whole or part. Users
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
/*
* Copyright (c) 1984 - 1991 by Sun Microsystems, Inc.
*/
/* #ident "@(#)rpcbind.c 1.19 94/04/25 SMI" */
#if 0
#ifndef lint
static char sccsid[] = "@(#)rpcbind.c 1.35 89/04/21 Copyr 1984 Sun Micro";
#endif
#endif
/*
* rpcbind.c
* Implements the program, version to address mapping for rpc.
*
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/errno.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/wait.h>
#include <sys/signal.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <rpc/rpc.h>
#ifdef PORTMAP
#include <netinet/in.h>
#endif
#include <netdb.h>
#include <stdio.h>
#include <netconfig.h>
#include <stdlib.h>
#include <unistd.h>
#include <syslog.h>
#include <err.h>
#include <util.h>
#include <pwd.h>
#include <semaphore.h>
#include <string.h>
#include <errno.h>
#include "rpcbind.h"
#include <rump/rump.h>
#include <rump/rump_syscalls.h>
/* Global variables */
int debugging = 1; /* Tell me what's going on */
int doabort = 0; /* When debugging, do an abort on errors */
rpcblist_ptr list_rbl; /* A list of version 3/4 rpcbind services */
#include "svc_fdset.h"
/* who to suid to if -s is given */
#define RUN_AS "daemon"
int runasdaemon = 0;
int insecure = 0;
int oldstyle_local = 0;
int verboselog = 0;
#ifdef WARMSTART
/* Local Variable */
static int warmstart = 0; /* Grab a old copy of registrations */
#endif
#ifdef PORTMAP
struct pmaplist *list_pml; /* A list of version 2 rpcbind services */
const char *udptrans; /* Name of UDP transport */
const char *tcptrans; /* Name of TCP transport */
const char *udp_uaddr; /* Universal UDP address */
const char *tcp_uaddr; /* Universal TCP address */
#endif
static const char servname[] = "sunrpc";
const char rpcbind_superuser[] = "superuser";
const char rpcbind_unknown[] = "unknown";
static int init_transport(struct netconfig *);
static void rbllist_add(rpcprog_t, rpcvers_t, struct netconfig *,
struct netbuf *);
static void terminate(int);
#if 0
static void parseargs(int, char *[]);
#endif
int rpcbind_main(void *);
int
rpcbind_main(void *arg)
{
struct netconfig *nconf;
void *nc_handle; /* Net config handle */
struct rlimit rl;
int maxrec = RPC_MAXDATASIZE;
extern sem_t gensem;
#if 0
parseargs(argc, argv);
#endif
alloc_fdset();
getrlimit(RLIMIT_NOFILE, &rl);
if (rl.rlim_cur < 128) {
if (rl.rlim_max <= 128)
rl.rlim_cur = rl.rlim_max;
else
rl.rlim_cur = 128;
setrlimit(RLIMIT_NOFILE, &rl);
}
#if 0
if (geteuid()) /* This command allowed only to root */
errx(1, "Sorry. You are not superuser");
#endif
nc_handle = setnetconfig(); /* open netconfig file */
if (nc_handle == NULL)
errx(1, "could not read /etc/netconfig");
#ifdef PORTMAP
udptrans = "";
tcptrans = "";
#endif
nconf = getnetconfigent("local");
if (nconf == NULL)
errx(1, "can't find local transport");
rpc_control(RPC_SVC_CONNMAXREC_SET, &maxrec);
init_transport(nconf);
while ((nconf = getnetconfig(nc_handle))) {
if (nconf->nc_flag & NC_VISIBLE)
init_transport(nconf);
}
endnetconfig(nc_handle);
/* catch the usual termination signals for graceful exit */
(void) signal(SIGCHLD, reap);
(void) signal(SIGINT, terminate);
(void) signal(SIGTERM, terminate);
(void) signal(SIGQUIT, terminate);
/* ignore others that could get sent */
(void) signal(SIGPIPE, SIG_IGN);
//(void) signal(SIGHUP, SIG_IGN); used by mountd
(void) signal(SIGUSR1, SIG_IGN);
(void) signal(SIGUSR2, SIG_IGN);
#ifdef WARMSTART
if (warmstart) {
read_warmstart();
}
#endif
if (debugging) {
printf("rpcbind debugging enabled.");
if (doabort) {
printf(" Will abort on errors!\n");
} else {
printf("\n");
}
} else {
if (daemon(0, 0))
err(1, "fork failed");
}
openlog("rpcbind", 0, LOG_DAEMON);
pidfile(NULL);
if (runasdaemon) {
struct passwd *p;
if((p = getpwnam(RUN_AS)) == NULL) {
syslog(LOG_ERR, "cannot get uid of daemon: %m");
exit(1);
}
if (setuid(p->pw_uid) == -1) {
syslog(LOG_ERR, "setuid to daemon failed: %m");
exit(1);
}
}
network_init();
sem_post(&gensem);
my_svc_run();
syslog(LOG_ERR, "svc_run returned unexpectedly");
rpcbind_abort();
/* NOTREACHED */
return 0;
}
/*
* Adds the entry into the rpcbind database.
* If PORTMAP, then for UDP and TCP, it adds the entries for version 2 also
* Returns 0 if succeeds, else fails
*/
static int
init_transport(struct netconfig *nconf)
{
int fd;
struct t_bind taddr;
struct addrinfo hints, *res = NULL;
struct __rpc_sockinfo si;
SVCXPRT *my_xprt;
int aicode, status, addrlen;
struct sockaddr *sa;
struct sockaddr_un sun;
const int one = 1;
if ((nconf->nc_semantics != NC_TPI_CLTS) &&
(nconf->nc_semantics != NC_TPI_COTS) &&
(nconf->nc_semantics != NC_TPI_COTS_ORD))
return 1; /* not my type */
#ifdef RPCBIND_DEBUG
if (debugging) {
int i;
char **s;
(void)fprintf(stderr, "%s: %ld lookup routines :\n",
nconf->nc_netid, nconf->nc_nlookups);
for (i = 0, s = nconf->nc_lookups; i < nconf->nc_nlookups;
i++, s++)
(void)fprintf(stderr, "[%d] - %s\n", i, *s);
}
#endif
/*
* XXX - using RPC library internal functions.
*/
if ((fd = __rpc_nconf2fd(nconf)) < 0) {
if (errno == EAFNOSUPPORT)
return 1;
warn("Cannot create socket for `%s'", nconf->nc_netid);
return 1;
}
if (!__rpc_nconf2sockinfo(nconf, &si)) {
warnx("Cannot get information for `%s'", nconf->nc_netid);
return 1;
}
if (si.si_af == AF_INET6) {
/*
* We're doing host-based access checks here, so don't allow
* v4-in-v6 to confuse things.
*/
if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &one,
sizeof one) < 0) {
warn("Can't make socket ipv6 only");
return 1;
}
}
if (!strcmp(nconf->nc_netid, "local")) {
(void)memset(&sun, 0, sizeof sun);
sun.sun_family = AF_LOCAL;
(void)rump_sys_unlink(_PATH_RPCBINDSOCK);
(void)strlcpy(sun.sun_path, _PATH_RPCBINDSOCK,
sizeof(sun.sun_path));
sun.sun_len = SUN_LEN(&sun);
addrlen = sizeof(struct sockaddr_un);
sa = (struct sockaddr *)&sun;
} else {
/* Get rpcbind's address on this transport */
(void)memset(&hints, 0, sizeof hints);
hints.ai_flags = AI_PASSIVE;
hints.ai_family = si.si_af;
hints.ai_socktype = si.si_socktype;
hints.ai_protocol = si.si_proto;
if ((aicode = getaddrinfo(NULL, servname, &hints, &res)) != 0) {
warnx("Cannot get local address for `%s' (%s)",
nconf->nc_netid, gai_strerror(aicode));
return 1;
}
addrlen = res->ai_addrlen;
sa = (struct sockaddr *)res->ai_addr;
}
if (bind(fd, sa, addrlen) < 0) {
warn("Cannot bind `%s'", nconf->nc_netid);
if (res != NULL)
freeaddrinfo(res);
return 1;
}
#if 0
if (sa->sa_family == AF_LOCAL)
if (rump_sys_chmod(sun.sun_path, S_IRWXU|S_IRWXG|S_IRWXO) == -1)
warn("Cannot chmod `%s'", sun.sun_path);
#endif
/* Copy the address */
taddr.addr.len = taddr.addr.maxlen = addrlen;
taddr.addr.buf = malloc(addrlen);
if (taddr.addr.buf == NULL) {
warn("Cannot allocate memory for `%s' address",
nconf->nc_netid);
if (res != NULL)
freeaddrinfo(res);
return 1;
}
(void)memcpy(taddr.addr.buf, sa, addrlen);
#ifdef RPCBIND_DEBUG
if (debugging) {
/* for debugging print out our universal address */
char *uaddr;
struct netbuf nb;
nb.buf = sa;
nb.len = nb.maxlen = sa->sa_len;
uaddr = taddr2uaddr(nconf, &nb);
(void)fprintf(stderr, "rpcbind: my address is %s\n", uaddr);
(void)free(uaddr);
}
#endif
if (res != NULL)
freeaddrinfo(res);
if (nconf->nc_semantics != NC_TPI_CLTS)
listen(fd, SOMAXCONN);
my_xprt = (SVCXPRT *)svc_tli_create(fd, nconf, &taddr, RPC_MAXDATASIZE,
RPC_MAXDATASIZE);
if (my_xprt == NULL) {
warnx("Could not create service for `%s'", nconf->nc_netid);
goto error;
}
#ifdef PORTMAP
/*
* Register both the versions for tcp/ip, udp/ip and local.
*/
if ((strcmp(nconf->nc_protofmly, NC_INET) == 0 &&
(strcmp(nconf->nc_proto, NC_TCP) == 0 ||
strcmp(nconf->nc_proto, NC_UDP) == 0)) ||
strcmp(nconf->nc_netid, "local") == 0) {
struct pmaplist *pml;
if (!svc_register(my_xprt, PMAPPROG, PMAPVERS,
pmap_service, 0)) {
warn("Could not register on `%s'", nconf->nc_netid);
goto error;
}
pml = malloc(sizeof (struct pmaplist));
if (pml == NULL) {
warn("Cannot allocate memory");
goto error;
}
pml->pml_map.pm_prog = PMAPPROG;
pml->pml_map.pm_vers = PMAPVERS;
pml->pml_map.pm_port = PMAPPORT;
if (strcmp(nconf->nc_proto, NC_TCP) == 0) {
if (tcptrans[0]) {
warnx(
"Cannot have more than one TCP transport");
free(pml);
goto error;
}
tcptrans = strdup(nconf->nc_netid);
if (tcptrans == NULL) {
free(pml);
warn("Cannot allocate memory");
goto error;
}
pml->pml_map.pm_prot = IPPROTO_TCP;
/* Let's snarf the universal address */
/* "h1.h2.h3.h4.p1.p2" */
tcp_uaddr = taddr2uaddr(nconf, &taddr.addr);
} else if (strcmp(nconf->nc_proto, NC_UDP) == 0) {
if (udptrans[0]) {
free(pml);
warnx(
"Cannot have more than one UDP transport");
goto error;
}
udptrans = strdup(nconf->nc_netid);
if (udptrans == NULL) {
free(pml);
warn("Cannot allocate memory");
goto error;
}
pml->pml_map.pm_prot = IPPROTO_UDP;
/* Let's snarf the universal address */
/* "h1.h2.h3.h4.p1.p2" */
udp_uaddr = taddr2uaddr(nconf, &taddr.addr);
}
pml->pml_next = list_pml;
list_pml = pml;
/* Add version 3 information */
pml = malloc(sizeof (struct pmaplist));
if (pml == NULL) {
warn("Cannot allocate memory");
goto error;
}
pml->pml_map = list_pml->pml_map;
pml->pml_map.pm_vers = RPCBVERS;
pml->pml_next = list_pml;
list_pml = pml;
/* Add version 4 information */
pml = malloc(sizeof (struct pmaplist));
if (pml == NULL) {
warn("Cannot allocate memory");
goto error;
}
pml->pml_map = list_pml->pml_map;
pml->pml_map.pm_vers = RPCBVERS4;
pml->pml_next = list_pml;
list_pml = pml;
/* Also add version 2 stuff to rpcbind list */
rbllist_add(PMAPPROG, PMAPVERS, nconf, &taddr.addr);
}
#endif
/* version 3 registration */
if (!svc_reg(my_xprt, RPCBPROG, RPCBVERS, rpcb_service_3, NULL)) {
warn("Could not register %s version 3", nconf->nc_netid);
goto error;
}
rbllist_add(RPCBPROG, RPCBVERS, nconf, &taddr.addr);
/* version 4 registration */
if (!svc_reg(my_xprt, RPCBPROG, RPCBVERS4, rpcb_service_4, NULL)) {
warn("Could not register %s version 4", nconf->nc_netid);
goto error;
}
rbllist_add(RPCBPROG, RPCBVERS4, nconf, &taddr.addr);
/* decide if bound checking works for this transport */
status = add_bndlist(nconf, &taddr.addr);
#ifdef RPCBIND_DEBUG
if (debugging) {
if (status < 0) {
fprintf(stderr, "Error in finding bind status for %s\n",
nconf->nc_netid);
} else if (status == 0) {
fprintf(stderr, "check binding for %s\n",
nconf->nc_netid);
} else if (status > 0) {
fprintf(stderr, "No check binding for %s\n",
nconf->nc_netid);
}
}
#else
__USE(status);
#endif
/*
* rmtcall only supported on CLTS transports for now.
*/
if (nconf->nc_semantics == NC_TPI_CLTS) {
status = create_rmtcall_fd(nconf);
#ifdef RPCBIND_DEBUG
if (debugging) {
if (status < 0) {
fprintf(stderr,
"Could not create rmtcall fd for %s\n",
nconf->nc_netid);
} else {
fprintf(stderr, "rmtcall fd for %s is %d\n",
nconf->nc_netid, status);
}
}
#endif
}
return (0);
error:
(void)rump_sys_close(fd);
return (1);
}
static void
rbllist_add(rpcprog_t prog, rpcvers_t vers, struct netconfig *nconf,
struct netbuf *addr)
{
rpcblist_ptr rbl;
rbl = malloc(sizeof(rpcblist));
if (rbl == NULL) {
warn("Out of memory");
return;
}
rbl->rpcb_map.r_prog = prog;
rbl->rpcb_map.r_vers = vers;
rbl->rpcb_map.r_netid = strdup(nconf->nc_netid);
rbl->rpcb_map.r_addr = taddr2uaddr(nconf, addr);
rbl->rpcb_map.r_owner = strdup(rpcbind_superuser);
rbl->rpcb_next = list_rbl; /* Attach to global list */
list_rbl = rbl;
}
/*
* Catch the signal and die
*/
static void
terminate(int dummy)
{
#ifdef WARMSTART
syslog(LOG_ERR,
"rpcbind terminating on signal. Restart with \"rpcbind -w\"");
write_warmstart(); /* Dump yourself */
#endif
exit(2);
}
void
rpcbind_abort()
{
#ifdef WARMSTART
write_warmstart(); /* Dump yourself */
#endif
abort();
}
#if 0
/* get command line options */
static void
parseargs(int argc, char *argv[])
{
int c;
while ((c = getopt(argc, argv, "dwailLs")) != -1) {
switch (c) {
case 'a':
doabort = 1; /* when debugging, do an abort on */
break; /* errors; for rpcbind developers */
/* only! */
case 'd':
debugging = 1;
break;
case 'i':
insecure = 1;
break;
case 'L':
oldstyle_local = 1;
break;
case 'l':
verboselog = 1;
break;
case 's':
runasdaemon = 1;
break;
#ifdef WARMSTART
case 'w':
warmstart = 1;
break;
#endif
default: /* error */
fprintf(stderr, "usage: rpcbind [-Idwils]\n");
exit (1);
}
}
if (doabort && !debugging) {
fprintf(stderr,
"-a (abort) specified without -d (debugging) -- ignored.\n");
doabort = 0;
}
}
#endif
void
reap(int dummy)
{
int save_errno = errno;
while (wait3(NULL, WNOHANG, NULL) > 0)
;
errno = save_errno;
}
void
toggle_verboselog(int dummy)
{
verboselog = !verboselog;
}

View File

@ -1,146 +0,0 @@
/* $NetBSD: rpcbind.h,v 1.1 2010/07/26 15:53:00 pooka Exp $ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
* media and as a part of the software program in whole or part. Users
* may copy or modify Sun RPC without charge, but are not authorized
* to license or distribute it to anyone else except as part of a product or
* program developed by the user.
*
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
*
* Sun RPC is provided with no support and without any obligation on the
* part of Sun Microsystems, Inc. to assist in its use, correction,
* modification or enhancement.
*
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
* OR ANY PART THEREOF.
*
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
* or profits or other special, indirect and consequential damages, even if
* Sun has been advised of the possibility of such damages.
*
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*/
/*
* Copyright (c) 1986 - 1991 by Sun Microsystems, Inc.
*/
/* #ident "@(#)rpcbind.h 1.4 90/04/12 SMI" */
/*
* rpcbind.h
* The common header declarations
*/
#ifndef rpcbind_h
#define rpcbind_h
#ifdef PORTMAP
#include <rpc/pmap_prot.h>
#endif
#include <rpc/rpcb_prot.h>
/*
* Stuff for the rmtcall service
*/
struct encap_parms {
u_int32_t arglen;
char *args;
};
struct r_rmtcall_args {
u_int32_t rmt_prog;
u_int32_t rmt_vers;
u_int32_t rmt_proc;
int rmt_localvers; /* whether to send port # or uaddr */
char *rmt_uaddr;
struct encap_parms rmt_args;
};
extern int debugging;
extern int doabort;
extern int verboselog;
extern int insecure;
extern int oldstyle_local;
extern rpcblist_ptr list_rbl; /* A list of version 3 & 4 rpcbind services */
#ifdef PORTMAP
extern struct pmaplist *list_pml; /* A list of version 2 rpcbind services */
extern const char *udptrans; /* Name of UDP transport */
extern const char *tcptrans; /* Name of TCP transport */
extern const char *udp_uaddr; /* Universal UDP address */
extern const char *tcp_uaddr; /* Universal TCP address */
#endif
extern const char rpcbind_superuser[];
extern const char rpcbind_unknown[];
int add_bndlist(struct netconfig *, struct netbuf *);
bool_t is_bound(const char *, const char *);
char *mergeaddr(SVCXPRT *, char *, char *, char *);
struct netconfig *rpcbind_get_conf(const char *);
void rpcbs_init(void);
void rpcbs_procinfo(rpcvers_t, rpcproc_t);
void rpcbs_set(rpcvers_t, bool_t);
void rpcbs_unset(rpcvers_t, bool_t);
void rpcbs_getaddr(rpcvers_t, rpcprog_t, rpcvers_t, const char *, const char *);
void rpcbs_rmtcall(rpcvers_t, rpcproc_t, rpcprog_t, rpcvers_t, rpcproc_t,
char *, rpcblist_ptr);
void *rpcbproc_getstat(void *, struct svc_req *, SVCXPRT *, rpcvers_t);
void rpcb_service_3(struct svc_req *, SVCXPRT *);
void rpcb_service_4(struct svc_req *, SVCXPRT *);
/* Common functions shared between versions */
void *rpcbproc_set_com(void *, struct svc_req *, SVCXPRT *, rpcvers_t);
void *rpcbproc_unset_com(void *, struct svc_req *, SVCXPRT *, rpcvers_t);
bool_t map_set(RPCB *, char *);
bool_t map_unset(RPCB *, const char *);
void delete_prog(int);
void *rpcbproc_getaddr_com(RPCB *, struct svc_req *, SVCXPRT *, rpcvers_t,
rpcvers_t);
void *rpcbproc_gettime_com(void *, struct svc_req *, SVCXPRT *,
rpcvers_t);
void *rpcbproc_uaddr2taddr_com(void *, struct svc_req *,
SVCXPRT *, rpcvers_t);
void *rpcbproc_taddr2uaddr_com(void *, struct svc_req *, SVCXPRT *,
rpcvers_t);
int create_rmtcall_fd(struct netconfig *);
void rpcbproc_callit_com(struct svc_req *, SVCXPRT *, rpcvers_t,
rpcvers_t);
void my_svc_run(void);
void rpcbind_abort(void);
void reap(int);
void toggle_verboselog(int);
int check_access(SVCXPRT *, rpcproc_t, void *, int);
int check_callit(SVCXPRT *, struct r_rmtcall_args *, int);
void logit(int, struct sockaddr *, rpcproc_t, rpcprog_t, const char *);
int is_loopback(struct netbuf *);
#ifdef PORTMAP
extern void pmap_service(struct svc_req *, SVCXPRT *);
#endif
void write_warmstart(void);
void read_warmstart(void);
char *addrmerge(struct netbuf *caller, char *serv_uaddr, char *clnt_uaddr,
char *netid);
void network_init(void);
struct sockaddr *local_sa(int);
/* For different getaddr semantics */
#define RPCB_ALLVERS 0
#define RPCB_ONEVERS 1
#endif /* rpcbind_h */

View File

@ -1,282 +0,0 @@
/* $NetBSD: security.c,v 1.1 2010/07/26 15:53:01 pooka Exp $ */
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <rpc/rpc.h>
#include <rpc/rpcb_prot.h>
#include <rpc/pmap_prot.h>
#include <err.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <util.h>
#include <syslog.h>
#include <netdb.h>
/*
* XXX for special case checks in check_callit.
*/
#include <rpcsvc/mount.h>
#include <rpcsvc/rquota.h>
#include <rpcsvc/nfs_prot.h>
#include <rpcsvc/yp.h>
#include <rpcsvc/ypclnt.h>
#include <rpcsvc/yppasswd.h>
#include "rpcbind.h"
#ifdef LIBWRAP
# include <tcpd.h>
#ifndef LIBWRAP_ALLOW_FACILITY
# define LIBWRAP_ALLOW_FACILITY LOG_AUTH
#endif
#ifndef LIBWRAP_ALLOW_SEVERITY
# define LIBWRAP_ALLOW_SEVERITY LOG_INFO
#endif
#ifndef LIBWRAP_DENY_FACILITY
# define LIBWRAP_DENY_FACILITY LOG_AUTH
#endif
#ifndef LIBWRAP_DENY_SEVERITY
# define LIBWRAP_DENY_SEVERITY LOG_WARNING
#endif
int allow_severity = LIBWRAP_ALLOW_FACILITY|LIBWRAP_ALLOW_SEVERITY;
int deny_severity = LIBWRAP_DENY_FACILITY|LIBWRAP_DENY_SEVERITY;
#endif
#ifndef PORTMAP_LOG_FACILITY
# define PORTMAP_LOG_FACILITY LOG_AUTH
#endif
#ifndef PORTMAP_LOG_SEVERITY
# define PORTMAP_LOG_SEVERITY LOG_INFO
#endif
int log_severity = PORTMAP_LOG_FACILITY|PORTMAP_LOG_SEVERITY;
extern int verboselog;
int
check_access(SVCXPRT *xprt, rpcproc_t proc, void *args, int rpcbvers)
{
struct netbuf *caller = svc_getrpccaller(xprt);
struct sockaddr *addr = (struct sockaddr *)caller->buf;
#ifdef LIBWRAP
struct request_info req;
#endif
rpcprog_t prog = 0;
rpcb *rpcbp;
struct pmap *pmap;
/*
* The older PMAP_* equivalents have the same numbers, so
* they are accounted for here as well.
*/
switch (proc) {
case RPCBPROC_GETADDR:
case RPCBPROC_SET:
case RPCBPROC_UNSET:
if (rpcbvers > PMAPVERS) {
rpcbp = (rpcb *)args;
prog = rpcbp->r_prog;
} else {
pmap = (struct pmap *)args;
prog = pmap->pm_prog;
}
if (proc == RPCBPROC_GETADDR)
break;
if (!insecure && !is_loopback(caller)) {
if (verboselog)
logit(log_severity, addr, proc, prog,
" declined (non-loopback sender)");
return 0;
}
break;
case RPCBPROC_CALLIT:
case RPCBPROC_INDIRECT:
case RPCBPROC_DUMP:
case RPCBPROC_GETTIME:
case RPCBPROC_UADDR2TADDR:
case RPCBPROC_TADDR2UADDR:
case RPCBPROC_GETVERSADDR:
case RPCBPROC_GETADDRLIST:
case RPCBPROC_GETSTAT:
default:
break;
}
#ifdef LIBWRAP
if (addr->sa_family == AF_LOCAL)
return 1;
request_init(&req, RQ_DAEMON, "rpcbind", RQ_CLIENT_SIN, addr, 0);
sock_methods(&req);
if(!hosts_access(&req)) {
logit(deny_severity, addr, proc, prog, ": request from unauthorized host");
return 0;
}
#endif
if (verboselog)
logit(log_severity, addr, proc, prog, "");
return 1;
}
int
is_loopback(struct netbuf *nbuf)
{
struct sockaddr *addr = (struct sockaddr *)nbuf->buf;
struct sockaddr_in *sin;
#ifdef INET6
struct sockaddr_in6 *sin6;
#endif
switch (addr->sa_family) {
case AF_INET:
if (!oldstyle_local)
return 0;
sin = (struct sockaddr_in *)addr;
return ((sin->sin_addr.s_addr == htonl(INADDR_LOOPBACK)) &&
(ntohs(sin->sin_port) < IPPORT_RESERVED));
#ifdef INET6
case AF_INET6:
if (!oldstyle_local)
return 0;
sin6 = (struct sockaddr_in6 *)addr;
return (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr) &&
(ntohs(sin6->sin6_port) < IPV6PORT_RESERVED));
#endif
case AF_LOCAL:
return 1;
default:
break;
}
return 0;
}
/* logit - report events of interest via the syslog daemon */
void
logit(int severity, struct sockaddr *addr, rpcproc_t procnum, rpcprog_t prognum,
const char *text)
{
const char *procname;
char procbuf[32];
char *progname;
char progbuf[32];
char fromname[NI_MAXHOST];
struct rpcent *rpc;
static const char *procmap[] = {
/* RPCBPROC_NULL */ "null",
/* RPCBPROC_SET */ "set",
/* RPCBPROC_UNSET */ "unset",
/* RPCBPROC_GETADDR */ "getport/addr",
/* RPCBPROC_DUMP */ "dump",
/* RPCBPROC_CALLIT */ "callit",
/* RPCBPROC_GETTIME */ "gettime",
/* RPCBPROC_UADDR2TADDR */ "uaddr2taddr",
/* RPCBPROC_TADDR2UADDR */ "taddr2uaddr",
/* RPCBPROC_GETVERSADDR */ "getversaddr",
/* RPCBPROC_INDIRECT */ "indirect",
/* RPCBPROC_GETADDRLIST */ "getaddrlist",
/* RPCBPROC_GETSTAT */ "getstat"
};
/*
* Fork off a process or the portmap daemon might hang while
* getrpcbynumber() or syslog() does its thing.
*/
if (fork() == 0) {
setproctitle("logit");
/* Try to map program number to name. */
if (prognum == 0) {
progname = __UNCONST("");
} else if ((rpc = getrpcbynumber((int) prognum))) {
progname = rpc->r_name;
} else {
snprintf(progname = progbuf, sizeof(progbuf), "%u",
(unsigned)prognum);
}
/* Try to map procedure number to name. */
if (procnum >= (sizeof procmap / sizeof (char *))) {
snprintf(procbuf, sizeof procbuf, "%u",
(unsigned)procnum);
procname = procbuf;
} else
procname = procmap[procnum];
/* Write syslog record. */
if (addr->sa_family == AF_LOCAL)
strlcpy(fromname, "local", sizeof(fromname));
else
getnameinfo(addr, addr->sa_len, fromname,
sizeof fromname, NULL, 0, NI_NUMERICHOST);
syslog(severity, "connect from %s to %s(%s)%s",
fromname, procname, progname, text);
_exit(0);
}
}
int
check_callit(SVCXPRT *xprt, struct r_rmtcall_args *args, int versnum)
{
struct sockaddr *sa = (struct sockaddr *)svc_getrpccaller(xprt)->buf;
/*
* Always allow calling NULLPROC
*/
if (args->rmt_proc == 0)
return 1;
/*
* XXX - this special casing sucks.
*/
switch (args->rmt_prog) {
case RPCBPROG:
/*
* Allow indirect calls to ourselves in insecure mode.
* The is_loopback checks aren't useful then anyway.
*/
if (!insecure)
goto deny;
break;
case MOUNTPROG:
if (args->rmt_proc != MOUNTPROC_MNT &&
args->rmt_proc != MOUNTPROC_UMNT)
break;
goto deny;
case YPBINDPROG:
if (args->rmt_proc != YPBINDPROC_SETDOM)
break;
/* FALLTHROUGH */
case YPPASSWDPROG:
case NFS_PROGRAM:
case RQUOTAPROG:
goto deny;
case YPPROG:
switch (args->rmt_proc) {
case YPPROC_ALL:
case YPPROC_MATCH:
case YPPROC_FIRST:
case YPPROC_NEXT:
goto deny;
default:
break;
}
default:
break;
}
return 1;
deny:
logit(deny_severity, sa, args->rmt_proc, args->rmt_prog,
": indirect call not allowed");
return 0;
}

View File

@ -1,401 +0,0 @@
/* $NetBSD: util.c,v 1.2 2011/06/11 18:03:17 christos Exp $ */
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Frank van der Linden.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/queue.h>
#include <net/if.h>
#include <netinet/in.h>
#include <assert.h>
#include <ifaddrs.h>
#include <poll.h>
#include <rpc/rpc.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>
#include <netconfig.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <rump/rump.h>
#include <rump/rump_syscalls.h>
#include "rpcbind.h"
static struct sockaddr_in *local_in4;
#ifdef INET6
static struct sockaddr_in6 *local_in6;
#endif
static int bitmaskcmp(void *, void *, void *, int);
#ifdef INET6
static void in6_fillscopeid(struct sockaddr_in6 *);
#endif
/*
* For all bits set in "mask", compare the corresponding bits in
* "dst" and "src", and see if they match.
*/
static int
bitmaskcmp(void *dst, void *src, void *mask, int bytelen)
{
int i, j;
u_int8_t *p1 = dst, *p2 = src, *netmask = mask;
u_int8_t bitmask;
for (i = 0; i < bytelen; i++) {
for (j = 0; j < 8; j++) {
bitmask = 1 << j;
if (!(netmask[i] & bitmask))
continue;
if ((p1[i] & bitmask) != (p2[i] & bitmask))
return 1;
}
}
return 0;
}
/*
* Taken from ifconfig.c
*/
#ifdef INET6
static void
in6_fillscopeid(struct sockaddr_in6 *sin6)
{
if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
sin6->sin6_scope_id =
ntohs(*(u_int16_t *)&sin6->sin6_addr.s6_addr[2]);
sin6->sin6_addr.s6_addr[2] = sin6->sin6_addr.s6_addr[3] = 0;
}
}
#endif
char *
addrmerge(struct netbuf *caller, char *serv_uaddr, char *clnt_uaddr,
char *netid)
{
struct ifaddrs *ifap, *ifp, *bestif;
#ifdef INET6
struct sockaddr_in6 *servsin6, *sin6mask, *clntsin6, *ifsin6, *realsin6;
struct sockaddr_in6 *newsin6;
#endif
struct sockaddr_in *servsin, *sinmask, *clntsin, *newsin, *ifsin;
struct netbuf *serv_nbp, *clnt_nbp = NULL, tbuf;
struct sockaddr *serv_sa;
struct sockaddr *clnt_sa;
struct sockaddr_storage ss;
struct netconfig *nconf;
struct sockaddr *clnt = caller->buf;
char *ret = NULL;
#ifdef INET6
servsin6 = ifsin6 = newsin6 = NULL; /* XXXGCC -Wuninitialized */
#endif
servsin = newsin = NULL; /* XXXGCC -Wuninitialized */
#ifdef RPCBIND_DEBUG
if (debugging)
fprintf(stderr, "addrmerge(caller, %s, %s, %s\n", serv_uaddr,
clnt_uaddr, netid);
#endif
nconf = getnetconfigent(netid);
if (nconf == NULL)
return NULL;
/*
* Local merge, just return a duplicate.
*/
if (clnt_uaddr != NULL && strncmp(clnt_uaddr, "0.0.0.0.", 8) == 0)
return strdup(clnt_uaddr);
serv_nbp = uaddr2taddr(nconf, serv_uaddr);
if (serv_nbp == NULL)
return NULL;
serv_sa = (struct sockaddr *)serv_nbp->buf;
if (clnt_uaddr != NULL) {
clnt_nbp = uaddr2taddr(nconf, clnt_uaddr);
if (clnt_nbp == NULL) {
free(serv_nbp);
return NULL;
}
clnt_sa = (struct sockaddr *)clnt_nbp->buf;
if (clnt_sa->sa_family == AF_LOCAL) {
free(serv_nbp);
free(clnt_nbp);
free(clnt_sa);
return strdup(serv_uaddr);
}
} else {
clnt_sa = (struct sockaddr *)
malloc(sizeof (struct sockaddr_storage));
memcpy(clnt_sa, clnt, clnt->sa_len);
}
if (getifaddrs(&ifp) < 0) {
free(serv_nbp);
free(clnt_sa);
if (clnt_nbp != NULL)
free(clnt_nbp);
return 0;
}
/*
* Loop through all interfaces. For each interface, see if the
* network portion of its address is equal to that of the client.
* If so, we have found the interface that we want to use.
*/
for (ifap = ifp; ifap != NULL; ifap = ifap->ifa_next) {
if (ifap->ifa_addr->sa_family != clnt->sa_family ||
!(ifap->ifa_flags & IFF_UP))
continue;
switch (clnt->sa_family) {
case AF_INET:
/*
* realsin: address that recvfrom gave us.
* ifsin: address of interface being examined.
* clntsin: address that client want us to contact
* it on
* servsin: local address of RPC service.
* sinmask: netmask of this interface
* newsin: initially a copy of clntsin, eventually
* the merged address
*/
servsin = (struct sockaddr_in *)serv_sa;
clntsin = (struct sockaddr_in *)clnt_sa;
sinmask = (struct sockaddr_in *)ifap->ifa_netmask;
newsin = (struct sockaddr_in *)&ss;
ifsin = (struct sockaddr_in *)ifap->ifa_addr;
if (!bitmaskcmp(&ifsin->sin_addr, &clntsin->sin_addr,
&sinmask->sin_addr, sizeof (struct in_addr))) {
goto found;
}
break;
#ifdef INET6
case AF_INET6:
/*
* realsin6: address that recvfrom gave us.
* ifsin6: address of interface being examined.
* clntsin6: address that client want us to contact
* it on
* servsin6: local address of RPC service.
* sin6mask: netmask of this interface
* newsin6: initially a copy of clntsin, eventually
* the merged address
*
* For v6 link local addresses, if the client contacted
* us via a link-local address, and wants us to reply
* to one, use the scope id to see which one.
*/
realsin6 = (struct sockaddr_in6 *)clnt;
ifsin6 = (struct sockaddr_in6 *)ifap->ifa_addr;
in6_fillscopeid(ifsin6);
clntsin6 = (struct sockaddr_in6 *)clnt_sa;
servsin6 = (struct sockaddr_in6 *)serv_sa;
sin6mask = (struct sockaddr_in6 *)ifap->ifa_netmask;
newsin6 = (struct sockaddr_in6 *)&ss;
if (IN6_IS_ADDR_LINKLOCAL(&ifsin6->sin6_addr) &&
IN6_IS_ADDR_LINKLOCAL(&realsin6->sin6_addr) &&
IN6_IS_ADDR_LINKLOCAL(&clntsin6->sin6_addr)) {
if (ifsin6->sin6_scope_id !=
realsin6->sin6_scope_id)
continue;
goto found;
}
if (!bitmaskcmp(&ifsin6->sin6_addr,
&clntsin6->sin6_addr, &sin6mask->sin6_addr,
sizeof (struct in6_addr)))
goto found;
break;
#endif
default:
goto freeit;
}
}
/*
* Didn't find anything. Get the first possibly useful interface,
* preferring "normal" interfaces to point-to-point and loopback
* ones.
*/
bestif = NULL;
for (ifap = ifp; ifap != NULL; ifap = ifap->ifa_next) {
if (ifap->ifa_addr->sa_family != clnt->sa_family ||
!(ifap->ifa_flags & IFF_UP))
continue;
if (!(ifap->ifa_flags & IFF_LOOPBACK) &&
!(ifap->ifa_flags & IFF_POINTOPOINT)) {
bestif = ifap;
break;
}
if (bestif == NULL)
bestif = ifap;
else if ((bestif->ifa_flags & IFF_LOOPBACK) &&
!(ifap->ifa_flags & IFF_LOOPBACK))
bestif = ifap;
}
ifap = bestif;
found:
switch (clnt->sa_family) {
case AF_INET:
memcpy(newsin, ifap->ifa_addr, clnt_sa->sa_len);
newsin->sin_port = servsin->sin_port;
tbuf.len = clnt_sa->sa_len;
tbuf.maxlen = sizeof (struct sockaddr_storage);
tbuf.buf = newsin;
break;
#ifdef INET6
case AF_INET6:
assert(newsin6);
memcpy(newsin6, ifsin6, clnt_sa->sa_len);
newsin6->sin6_port = servsin6->sin6_port;
tbuf.maxlen = sizeof (struct sockaddr_storage);
tbuf.len = clnt_sa->sa_len;
tbuf.buf = newsin6;
break;
#endif
default:
goto freeit;
}
if (ifap != NULL)
ret = taddr2uaddr(nconf, &tbuf);
freeit:
freenetconfigent(nconf);
free(serv_sa);
free(serv_nbp);
if (clnt_sa != NULL)
free(clnt_sa);
if (clnt_nbp != NULL)
free(clnt_nbp);
freeifaddrs(ifp);
#ifdef RPCBIND_DEBUG
if (debugging)
fprintf(stderr, "addrmerge: returning %s\n", ret);
#endif
return ret;
}
void
network_init()
{
#ifdef INET6
struct ifaddrs *ifap, *ifp;
struct ipv6_mreq mreq6;
int ifindex, s;
#endif
int ecode;
struct addrinfo hints, *res;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_INET;
if ((ecode = getaddrinfo(NULL, "sunrpc", &hints, &res))) {
if (debugging)
fprintf(stderr, "can't get local ip4 address: %s\n",
gai_strerror(ecode));
} else {
local_in4 = (struct sockaddr_in *)malloc(sizeof *local_in4);
if (local_in4 == NULL) {
if (debugging)
fprintf(stderr, "can't alloc local ip4 addr\n");
}
memcpy(local_in4, res->ai_addr, sizeof *local_in4);
}
#ifdef INET6
hints.ai_family = AF_INET6;
if ((ecode = getaddrinfo(NULL, "sunrpc", &hints, &res))) {
if (debugging)
fprintf(stderr, "can't get local ip6 address: %s\n",
gai_strerror(ecode));
} else {
local_in6 = (struct sockaddr_in6 *)malloc(sizeof *local_in6);
if (local_in6 == NULL) {
if (debugging)
fprintf(stderr, "can't alloc local ip6 addr\n");
}
memcpy(local_in6, res->ai_addr, sizeof *local_in6);
}
/*
* Now join the RPC ipv6 multicast group on all interfaces.
*/
if (getifaddrs(&ifp) < 0)
return;
mreq6.ipv6mr_interface = 0;
inet_pton(AF_INET6, RPCB_MULTICAST_ADDR, &mreq6.ipv6mr_multiaddr);
s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
/*
* Loop through all interfaces. For each interface, see if the
* network portion of its address is equal to that of the client.
* If so, we have found the interface that we want to use.
*/
for (ifap = ifp; ifap != NULL; ifap = ifap->ifa_next) {
if (ifap->ifa_addr->sa_family != AF_INET6 ||
!(ifap->ifa_flags & IFF_MULTICAST))
continue;
ifindex = if_nametoindex(ifap->ifa_name);
if (ifindex == mreq6.ipv6mr_interface)
/*
* Already did this one.
*/
continue;
mreq6.ipv6mr_interface = ifindex;
if (setsockopt(s, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq6,
sizeof mreq6) < 0)
if (debugging)
warn("setsockopt v6 multicast");
}
#endif
/* close(s); */
}
struct sockaddr *
local_sa(int af)
{
switch (af) {
case AF_INET:
return (struct sockaddr *)local_in4;
#ifdef INET6
case AF_INET6:
return (struct sockaddr *)local_in6;
#endif
default:
return NULL;
}
}