1*0a6a1f1dSLionel Sambuc /* $NetBSD: rpcbind.c,v 1.5 2015/08/21 14:19:10 christos Exp $ */
211be35a1SLionel Sambuc
311be35a1SLionel Sambuc /*
411be35a1SLionel Sambuc * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
511be35a1SLionel Sambuc * unrestricted use provided that this legend is included on all tape
611be35a1SLionel Sambuc * media and as a part of the software program in whole or part. Users
711be35a1SLionel Sambuc * may copy or modify Sun RPC without charge, but are not authorized
811be35a1SLionel Sambuc * to license or distribute it to anyone else except as part of a product or
911be35a1SLionel Sambuc * program developed by the user.
1011be35a1SLionel Sambuc *
1111be35a1SLionel Sambuc * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
1211be35a1SLionel Sambuc * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
1311be35a1SLionel Sambuc * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
1411be35a1SLionel Sambuc *
1511be35a1SLionel Sambuc * Sun RPC is provided with no support and without any obligation on the
1611be35a1SLionel Sambuc * part of Sun Microsystems, Inc. to assist in its use, correction,
1711be35a1SLionel Sambuc * modification or enhancement.
1811be35a1SLionel Sambuc *
1911be35a1SLionel Sambuc * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
2011be35a1SLionel Sambuc * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
2111be35a1SLionel Sambuc * OR ANY PART THEREOF.
2211be35a1SLionel Sambuc *
2311be35a1SLionel Sambuc * In no event will Sun Microsystems, Inc. be liable for any lost revenue
2411be35a1SLionel Sambuc * or profits or other special, indirect and consequential damages, even if
2511be35a1SLionel Sambuc * Sun has been advised of the possibility of such damages.
2611be35a1SLionel Sambuc *
2711be35a1SLionel Sambuc * Sun Microsystems, Inc.
2811be35a1SLionel Sambuc * 2550 Garcia Avenue
2911be35a1SLionel Sambuc * Mountain View, California 94043
3011be35a1SLionel Sambuc */
3111be35a1SLionel Sambuc /*
3211be35a1SLionel Sambuc * Copyright (c) 1984 - 1991 by Sun Microsystems, Inc.
3311be35a1SLionel Sambuc */
3411be35a1SLionel Sambuc
3511be35a1SLionel Sambuc /* #ident "@(#)rpcbind.c 1.19 94/04/25 SMI" */
3611be35a1SLionel Sambuc
3711be35a1SLionel Sambuc #if 0
3811be35a1SLionel Sambuc #ifndef lint
3911be35a1SLionel Sambuc static char sccsid[] = "@(#)rpcbind.c 1.35 89/04/21 Copyr 1984 Sun Micro";
4011be35a1SLionel Sambuc #endif
4111be35a1SLionel Sambuc #endif
4211be35a1SLionel Sambuc
4311be35a1SLionel Sambuc /*
4411be35a1SLionel Sambuc * rpcbind.c
4511be35a1SLionel Sambuc * Implements the program, version to address mapping for rpc.
4611be35a1SLionel Sambuc *
4711be35a1SLionel Sambuc */
4811be35a1SLionel Sambuc
4911be35a1SLionel Sambuc #include <sys/types.h>
5011be35a1SLionel Sambuc #include <sys/stat.h>
5111be35a1SLionel Sambuc #include <sys/errno.h>
5211be35a1SLionel Sambuc #include <sys/time.h>
5311be35a1SLionel Sambuc #include <sys/resource.h>
5411be35a1SLionel Sambuc #include <sys/wait.h>
5511be35a1SLionel Sambuc #include <sys/signal.h>
5611be35a1SLionel Sambuc #include <sys/socket.h>
5711be35a1SLionel Sambuc #include <sys/un.h>
5811be35a1SLionel Sambuc #include <rpc/rpc.h>
5911be35a1SLionel Sambuc #ifdef PORTMAP
6011be35a1SLionel Sambuc #include <netinet/in.h>
6111be35a1SLionel Sambuc #endif
6211be35a1SLionel Sambuc #include <netdb.h>
6311be35a1SLionel Sambuc #include <stdio.h>
6411be35a1SLionel Sambuc #include <netconfig.h>
6511be35a1SLionel Sambuc #include <stdlib.h>
6611be35a1SLionel Sambuc #include <unistd.h>
6711be35a1SLionel Sambuc #include <syslog.h>
6811be35a1SLionel Sambuc #include <err.h>
6911be35a1SLionel Sambuc #include <util.h>
7011be35a1SLionel Sambuc #include <pwd.h>
7111be35a1SLionel Sambuc #include <semaphore.h>
7211be35a1SLionel Sambuc #include <string.h>
7311be35a1SLionel Sambuc #include <errno.h>
7411be35a1SLionel Sambuc #include "rpcbind.h"
7511be35a1SLionel Sambuc
7611be35a1SLionel Sambuc #include <rump/rump.h>
7711be35a1SLionel Sambuc #include <rump/rump_syscalls.h>
7811be35a1SLionel Sambuc
7911be35a1SLionel Sambuc /* Global variables */
8011be35a1SLionel Sambuc int debugging = 1; /* Tell me what's going on */
8111be35a1SLionel Sambuc int doabort = 0; /* When debugging, do an abort on errors */
8211be35a1SLionel Sambuc rpcblist_ptr list_rbl; /* A list of version 3/4 rpcbind services */
8311be35a1SLionel Sambuc
8411be35a1SLionel Sambuc #include "svc_fdset.h"
8511be35a1SLionel Sambuc
8611be35a1SLionel Sambuc /* who to suid to if -s is given */
8711be35a1SLionel Sambuc #define RUN_AS "daemon"
8811be35a1SLionel Sambuc
8911be35a1SLionel Sambuc int runasdaemon = 0;
9011be35a1SLionel Sambuc int insecure = 0;
9111be35a1SLionel Sambuc int oldstyle_local = 0;
9211be35a1SLionel Sambuc int verboselog = 0;
9311be35a1SLionel Sambuc
9411be35a1SLionel Sambuc #ifdef WARMSTART
9511be35a1SLionel Sambuc /* Local Variable */
9611be35a1SLionel Sambuc static int warmstart = 0; /* Grab a old copy of registrations */
9711be35a1SLionel Sambuc #endif
9811be35a1SLionel Sambuc
9911be35a1SLionel Sambuc #ifdef PORTMAP
10011be35a1SLionel Sambuc struct pmaplist *list_pml; /* A list of version 2 rpcbind services */
10111be35a1SLionel Sambuc const char *udptrans; /* Name of UDP transport */
10211be35a1SLionel Sambuc const char *tcptrans; /* Name of TCP transport */
10311be35a1SLionel Sambuc const char *udp_uaddr; /* Universal UDP address */
10411be35a1SLionel Sambuc const char *tcp_uaddr; /* Universal TCP address */
10511be35a1SLionel Sambuc #endif
10611be35a1SLionel Sambuc static const char servname[] = "sunrpc";
10711be35a1SLionel Sambuc
10811be35a1SLionel Sambuc const char rpcbind_superuser[] = "superuser";
10911be35a1SLionel Sambuc const char rpcbind_unknown[] = "unknown";
11011be35a1SLionel Sambuc
11111be35a1SLionel Sambuc static int init_transport(struct netconfig *);
11211be35a1SLionel Sambuc static void rbllist_add(rpcprog_t, rpcvers_t, struct netconfig *,
11311be35a1SLionel Sambuc struct netbuf *);
11411be35a1SLionel Sambuc static void terminate(int);
11511be35a1SLionel Sambuc #if 0
11611be35a1SLionel Sambuc static void parseargs(int, char *[]);
11711be35a1SLionel Sambuc #endif
11811be35a1SLionel Sambuc
11911be35a1SLionel Sambuc int rpcbind_main(void *);
12011be35a1SLionel Sambuc int
rpcbind_main(void * arg)12111be35a1SLionel Sambuc rpcbind_main(void *arg)
12211be35a1SLionel Sambuc {
12311be35a1SLionel Sambuc struct netconfig *nconf;
12411be35a1SLionel Sambuc void *nc_handle; /* Net config handle */
12511be35a1SLionel Sambuc struct rlimit rl;
12611be35a1SLionel Sambuc int maxrec = RPC_MAXDATASIZE;
12711be35a1SLionel Sambuc extern sem_t gensem;
12811be35a1SLionel Sambuc
12911be35a1SLionel Sambuc #if 0
13011be35a1SLionel Sambuc parseargs(argc, argv);
13111be35a1SLionel Sambuc #endif
13211be35a1SLionel Sambuc
13311be35a1SLionel Sambuc alloc_fdset();
13411be35a1SLionel Sambuc
13511be35a1SLionel Sambuc getrlimit(RLIMIT_NOFILE, &rl);
13611be35a1SLionel Sambuc if (rl.rlim_cur < 128) {
13711be35a1SLionel Sambuc if (rl.rlim_max <= 128)
13811be35a1SLionel Sambuc rl.rlim_cur = rl.rlim_max;
13911be35a1SLionel Sambuc else
14011be35a1SLionel Sambuc rl.rlim_cur = 128;
14111be35a1SLionel Sambuc setrlimit(RLIMIT_NOFILE, &rl);
14211be35a1SLionel Sambuc }
14311be35a1SLionel Sambuc #if 0
14411be35a1SLionel Sambuc if (geteuid()) /* This command allowed only to root */
14511be35a1SLionel Sambuc errx(1, "Sorry. You are not superuser");
14611be35a1SLionel Sambuc #endif
14711be35a1SLionel Sambuc nc_handle = setnetconfig(); /* open netconfig file */
14811be35a1SLionel Sambuc if (nc_handle == NULL)
14911be35a1SLionel Sambuc errx(1, "could not read /etc/netconfig");
15011be35a1SLionel Sambuc #ifdef PORTMAP
15111be35a1SLionel Sambuc udptrans = "";
15211be35a1SLionel Sambuc tcptrans = "";
15311be35a1SLionel Sambuc #endif
15411be35a1SLionel Sambuc
15511be35a1SLionel Sambuc nconf = getnetconfigent("local");
15611be35a1SLionel Sambuc if (nconf == NULL)
15711be35a1SLionel Sambuc errx(1, "can't find local transport");
15811be35a1SLionel Sambuc
15911be35a1SLionel Sambuc rpc_control(RPC_SVC_CONNMAXREC_SET, &maxrec);
16011be35a1SLionel Sambuc
16111be35a1SLionel Sambuc init_transport(nconf);
16211be35a1SLionel Sambuc
16311be35a1SLionel Sambuc while ((nconf = getnetconfig(nc_handle))) {
16411be35a1SLionel Sambuc if (nconf->nc_flag & NC_VISIBLE)
16511be35a1SLionel Sambuc init_transport(nconf);
16611be35a1SLionel Sambuc }
16711be35a1SLionel Sambuc endnetconfig(nc_handle);
16811be35a1SLionel Sambuc
16911be35a1SLionel Sambuc /* catch the usual termination signals for graceful exit */
17011be35a1SLionel Sambuc (void) signal(SIGCHLD, reap);
17111be35a1SLionel Sambuc (void) signal(SIGINT, terminate);
17211be35a1SLionel Sambuc (void) signal(SIGTERM, terminate);
17311be35a1SLionel Sambuc (void) signal(SIGQUIT, terminate);
17411be35a1SLionel Sambuc /* ignore others that could get sent */
17511be35a1SLionel Sambuc (void) signal(SIGPIPE, SIG_IGN);
17611be35a1SLionel Sambuc //(void) signal(SIGHUP, SIG_IGN); used by mountd
17711be35a1SLionel Sambuc (void) signal(SIGUSR1, SIG_IGN);
17811be35a1SLionel Sambuc (void) signal(SIGUSR2, SIG_IGN);
17911be35a1SLionel Sambuc #ifdef WARMSTART
18011be35a1SLionel Sambuc if (warmstart) {
18111be35a1SLionel Sambuc read_warmstart();
18211be35a1SLionel Sambuc }
18311be35a1SLionel Sambuc #endif
18411be35a1SLionel Sambuc if (debugging) {
18511be35a1SLionel Sambuc printf("rpcbind debugging enabled.");
18611be35a1SLionel Sambuc if (doabort) {
18711be35a1SLionel Sambuc printf(" Will abort on errors!\n");
18811be35a1SLionel Sambuc } else {
18911be35a1SLionel Sambuc printf("\n");
19011be35a1SLionel Sambuc }
19111be35a1SLionel Sambuc } else {
19211be35a1SLionel Sambuc if (daemon(0, 0))
19311be35a1SLionel Sambuc err(1, "fork failed");
19411be35a1SLionel Sambuc }
19511be35a1SLionel Sambuc
19611be35a1SLionel Sambuc openlog("rpcbind", 0, LOG_DAEMON);
19711be35a1SLionel Sambuc pidfile(NULL);
19811be35a1SLionel Sambuc
19911be35a1SLionel Sambuc if (runasdaemon) {
20011be35a1SLionel Sambuc struct passwd *p;
20111be35a1SLionel Sambuc
20211be35a1SLionel Sambuc if ((p = getpwnam(RUN_AS)) == NULL) {
203*0a6a1f1dSLionel Sambuc syslog(LOG_ERR, "cannot get uid of daemon (%s)",
204*0a6a1f1dSLionel Sambuc strerror(errno));
20511be35a1SLionel Sambuc exit(1);
20611be35a1SLionel Sambuc }
20711be35a1SLionel Sambuc if (setuid(p->pw_uid) == -1) {
208*0a6a1f1dSLionel Sambuc syslog(LOG_ERR, "setuid to daemon failed: (%s)",
209*0a6a1f1dSLionel Sambuc strerror(errno));
21011be35a1SLionel Sambuc exit(1);
21111be35a1SLionel Sambuc }
21211be35a1SLionel Sambuc }
21311be35a1SLionel Sambuc
21411be35a1SLionel Sambuc network_init();
21511be35a1SLionel Sambuc
21611be35a1SLionel Sambuc sem_post(&gensem);
21711be35a1SLionel Sambuc my_svc_run();
21811be35a1SLionel Sambuc syslog(LOG_ERR, "svc_run returned unexpectedly");
21911be35a1SLionel Sambuc rpcbind_abort();
22011be35a1SLionel Sambuc /* NOTREACHED */
22111be35a1SLionel Sambuc
22211be35a1SLionel Sambuc return 0;
22311be35a1SLionel Sambuc }
22411be35a1SLionel Sambuc
22511be35a1SLionel Sambuc /*
22611be35a1SLionel Sambuc * Adds the entry into the rpcbind database.
22711be35a1SLionel Sambuc * If PORTMAP, then for UDP and TCP, it adds the entries for version 2 also
22811be35a1SLionel Sambuc * Returns 0 if succeeds, else fails
22911be35a1SLionel Sambuc */
23011be35a1SLionel Sambuc static int
init_transport(struct netconfig * nconf)23111be35a1SLionel Sambuc init_transport(struct netconfig *nconf)
23211be35a1SLionel Sambuc {
23311be35a1SLionel Sambuc int fd;
23411be35a1SLionel Sambuc struct t_bind taddr;
23511be35a1SLionel Sambuc struct addrinfo hints, *res = NULL;
23611be35a1SLionel Sambuc struct __rpc_sockinfo si;
23711be35a1SLionel Sambuc SVCXPRT *my_xprt;
23884d9c625SLionel Sambuc int aicode, status, addrlen;
23911be35a1SLionel Sambuc struct sockaddr *sa;
24011be35a1SLionel Sambuc struct sockaddr_un sun;
24111be35a1SLionel Sambuc const int one = 1;
24211be35a1SLionel Sambuc
24311be35a1SLionel Sambuc if ((nconf->nc_semantics != NC_TPI_CLTS) &&
24411be35a1SLionel Sambuc (nconf->nc_semantics != NC_TPI_COTS) &&
24511be35a1SLionel Sambuc (nconf->nc_semantics != NC_TPI_COTS_ORD))
24611be35a1SLionel Sambuc return 1; /* not my type */
24711be35a1SLionel Sambuc #ifdef RPCBIND_DEBUG
24811be35a1SLionel Sambuc if (debugging) {
24911be35a1SLionel Sambuc int i;
25011be35a1SLionel Sambuc char **s;
25111be35a1SLionel Sambuc
25211be35a1SLionel Sambuc (void)fprintf(stderr, "%s: %ld lookup routines :\n",
25311be35a1SLionel Sambuc nconf->nc_netid, nconf->nc_nlookups);
25411be35a1SLionel Sambuc for (i = 0, s = nconf->nc_lookups; i < nconf->nc_nlookups;
25511be35a1SLionel Sambuc i++, s++)
25611be35a1SLionel Sambuc (void)fprintf(stderr, "[%d] - %s\n", i, *s);
25711be35a1SLionel Sambuc }
25811be35a1SLionel Sambuc #endif
25911be35a1SLionel Sambuc
26011be35a1SLionel Sambuc /*
26111be35a1SLionel Sambuc * XXX - using RPC library internal functions.
26211be35a1SLionel Sambuc */
26311be35a1SLionel Sambuc if ((fd = __rpc_nconf2fd(nconf)) < 0) {
26411be35a1SLionel Sambuc if (errno == EAFNOSUPPORT)
26511be35a1SLionel Sambuc return 1;
26611be35a1SLionel Sambuc warn("Cannot create socket for `%s'", nconf->nc_netid);
26711be35a1SLionel Sambuc return 1;
26811be35a1SLionel Sambuc }
26911be35a1SLionel Sambuc
27011be35a1SLionel Sambuc if (!__rpc_nconf2sockinfo(nconf, &si)) {
27111be35a1SLionel Sambuc warnx("Cannot get information for `%s'", nconf->nc_netid);
27211be35a1SLionel Sambuc return 1;
27311be35a1SLionel Sambuc }
27411be35a1SLionel Sambuc
27511be35a1SLionel Sambuc if (si.si_af == AF_INET6) {
27611be35a1SLionel Sambuc /*
27711be35a1SLionel Sambuc * We're doing host-based access checks here, so don't allow
27811be35a1SLionel Sambuc * v4-in-v6 to confuse things.
27911be35a1SLionel Sambuc */
28011be35a1SLionel Sambuc if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &one,
28111be35a1SLionel Sambuc sizeof one) < 0) {
28211be35a1SLionel Sambuc warn("Can't make socket ipv6 only");
28311be35a1SLionel Sambuc return 1;
28411be35a1SLionel Sambuc }
28511be35a1SLionel Sambuc }
28611be35a1SLionel Sambuc
28711be35a1SLionel Sambuc
28811be35a1SLionel Sambuc if (!strcmp(nconf->nc_netid, "local")) {
28911be35a1SLionel Sambuc (void)memset(&sun, 0, sizeof sun);
29011be35a1SLionel Sambuc sun.sun_family = AF_LOCAL;
29111be35a1SLionel Sambuc (void)rump_sys_unlink(_PATH_RPCBINDSOCK);
29211be35a1SLionel Sambuc (void)strlcpy(sun.sun_path, _PATH_RPCBINDSOCK,
29311be35a1SLionel Sambuc sizeof(sun.sun_path));
29411be35a1SLionel Sambuc sun.sun_len = SUN_LEN(&sun);
29511be35a1SLionel Sambuc addrlen = sizeof(struct sockaddr_un);
29611be35a1SLionel Sambuc sa = (struct sockaddr *)&sun;
29711be35a1SLionel Sambuc } else {
29811be35a1SLionel Sambuc /* Get rpcbind's address on this transport */
29911be35a1SLionel Sambuc
30011be35a1SLionel Sambuc (void)memset(&hints, 0, sizeof hints);
30111be35a1SLionel Sambuc hints.ai_flags = AI_PASSIVE;
30211be35a1SLionel Sambuc hints.ai_family = si.si_af;
30311be35a1SLionel Sambuc hints.ai_socktype = si.si_socktype;
30411be35a1SLionel Sambuc hints.ai_protocol = si.si_proto;
30511be35a1SLionel Sambuc if ((aicode = getaddrinfo(NULL, servname, &hints, &res)) != 0) {
30611be35a1SLionel Sambuc warnx("Cannot get local address for `%s' (%s)",
30711be35a1SLionel Sambuc nconf->nc_netid, gai_strerror(aicode));
30811be35a1SLionel Sambuc return 1;
30911be35a1SLionel Sambuc }
31011be35a1SLionel Sambuc addrlen = res->ai_addrlen;
31111be35a1SLionel Sambuc sa = (struct sockaddr *)res->ai_addr;
31211be35a1SLionel Sambuc }
31311be35a1SLionel Sambuc
31411be35a1SLionel Sambuc if (bind(fd, sa, addrlen) < 0) {
31511be35a1SLionel Sambuc warn("Cannot bind `%s'", nconf->nc_netid);
31611be35a1SLionel Sambuc if (res != NULL)
31711be35a1SLionel Sambuc freeaddrinfo(res);
31811be35a1SLionel Sambuc return 1;
31911be35a1SLionel Sambuc }
32011be35a1SLionel Sambuc #if 0
32111be35a1SLionel Sambuc if (sa->sa_family == AF_LOCAL)
32211be35a1SLionel Sambuc if (rump_sys_chmod(sun.sun_path, S_IRWXU|S_IRWXG|S_IRWXO) == -1)
32311be35a1SLionel Sambuc warn("Cannot chmod `%s'", sun.sun_path);
32411be35a1SLionel Sambuc #endif
32511be35a1SLionel Sambuc
32611be35a1SLionel Sambuc /* Copy the address */
32711be35a1SLionel Sambuc taddr.addr.len = taddr.addr.maxlen = addrlen;
32811be35a1SLionel Sambuc taddr.addr.buf = malloc(addrlen);
32911be35a1SLionel Sambuc if (taddr.addr.buf == NULL) {
33011be35a1SLionel Sambuc warn("Cannot allocate memory for `%s' address",
33111be35a1SLionel Sambuc nconf->nc_netid);
33211be35a1SLionel Sambuc if (res != NULL)
33311be35a1SLionel Sambuc freeaddrinfo(res);
33411be35a1SLionel Sambuc return 1;
33511be35a1SLionel Sambuc }
33611be35a1SLionel Sambuc (void)memcpy(taddr.addr.buf, sa, addrlen);
33711be35a1SLionel Sambuc #ifdef RPCBIND_DEBUG
33811be35a1SLionel Sambuc if (debugging) {
33911be35a1SLionel Sambuc /* for debugging print out our universal address */
34011be35a1SLionel Sambuc char *uaddr;
34111be35a1SLionel Sambuc struct netbuf nb;
34211be35a1SLionel Sambuc
34311be35a1SLionel Sambuc nb.buf = sa;
34411be35a1SLionel Sambuc nb.len = nb.maxlen = sa->sa_len;
34511be35a1SLionel Sambuc uaddr = taddr2uaddr(nconf, &nb);
34611be35a1SLionel Sambuc (void)fprintf(stderr, "rpcbind: my address is %s\n", uaddr);
34711be35a1SLionel Sambuc (void)free(uaddr);
34811be35a1SLionel Sambuc }
34911be35a1SLionel Sambuc #endif
35011be35a1SLionel Sambuc
35111be35a1SLionel Sambuc if (res != NULL)
35211be35a1SLionel Sambuc freeaddrinfo(res);
35311be35a1SLionel Sambuc
35411be35a1SLionel Sambuc if (nconf->nc_semantics != NC_TPI_CLTS)
35511be35a1SLionel Sambuc listen(fd, SOMAXCONN);
35611be35a1SLionel Sambuc
35711be35a1SLionel Sambuc my_xprt = (SVCXPRT *)svc_tli_create(fd, nconf, &taddr, RPC_MAXDATASIZE,
35811be35a1SLionel Sambuc RPC_MAXDATASIZE);
35911be35a1SLionel Sambuc if (my_xprt == NULL) {
36011be35a1SLionel Sambuc warnx("Could not create service for `%s'", nconf->nc_netid);
36111be35a1SLionel Sambuc goto error;
36211be35a1SLionel Sambuc }
36311be35a1SLionel Sambuc
36411be35a1SLionel Sambuc #ifdef PORTMAP
36511be35a1SLionel Sambuc /*
36611be35a1SLionel Sambuc * Register both the versions for tcp/ip, udp/ip and local.
36711be35a1SLionel Sambuc */
36811be35a1SLionel Sambuc if ((strcmp(nconf->nc_protofmly, NC_INET) == 0 &&
36911be35a1SLionel Sambuc (strcmp(nconf->nc_proto, NC_TCP) == 0 ||
37011be35a1SLionel Sambuc strcmp(nconf->nc_proto, NC_UDP) == 0)) ||
37111be35a1SLionel Sambuc strcmp(nconf->nc_netid, "local") == 0) {
37211be35a1SLionel Sambuc struct pmaplist *pml;
37311be35a1SLionel Sambuc
37411be35a1SLionel Sambuc if (!svc_register(my_xprt, PMAPPROG, PMAPVERS,
37511be35a1SLionel Sambuc pmap_service, 0)) {
37611be35a1SLionel Sambuc warn("Could not register on `%s'", nconf->nc_netid);
37711be35a1SLionel Sambuc goto error;
37811be35a1SLionel Sambuc }
37911be35a1SLionel Sambuc pml = malloc(sizeof (struct pmaplist));
38011be35a1SLionel Sambuc if (pml == NULL) {
38111be35a1SLionel Sambuc warn("Cannot allocate memory");
38211be35a1SLionel Sambuc goto error;
38311be35a1SLionel Sambuc }
38411be35a1SLionel Sambuc pml->pml_map.pm_prog = PMAPPROG;
38511be35a1SLionel Sambuc pml->pml_map.pm_vers = PMAPVERS;
38611be35a1SLionel Sambuc pml->pml_map.pm_port = PMAPPORT;
38711be35a1SLionel Sambuc if (strcmp(nconf->nc_proto, NC_TCP) == 0) {
38811be35a1SLionel Sambuc if (tcptrans[0]) {
38911be35a1SLionel Sambuc warnx(
39011be35a1SLionel Sambuc "Cannot have more than one TCP transport");
39111be35a1SLionel Sambuc free(pml);
39211be35a1SLionel Sambuc goto error;
39311be35a1SLionel Sambuc }
39411be35a1SLionel Sambuc tcptrans = strdup(nconf->nc_netid);
39511be35a1SLionel Sambuc if (tcptrans == NULL) {
39611be35a1SLionel Sambuc free(pml);
39711be35a1SLionel Sambuc warn("Cannot allocate memory");
39811be35a1SLionel Sambuc goto error;
39911be35a1SLionel Sambuc }
40011be35a1SLionel Sambuc pml->pml_map.pm_prot = IPPROTO_TCP;
40111be35a1SLionel Sambuc
40211be35a1SLionel Sambuc /* Let's snarf the universal address */
40311be35a1SLionel Sambuc /* "h1.h2.h3.h4.p1.p2" */
40411be35a1SLionel Sambuc tcp_uaddr = taddr2uaddr(nconf, &taddr.addr);
40511be35a1SLionel Sambuc } else if (strcmp(nconf->nc_proto, NC_UDP) == 0) {
40611be35a1SLionel Sambuc if (udptrans[0]) {
40711be35a1SLionel Sambuc free(pml);
40811be35a1SLionel Sambuc warnx(
40911be35a1SLionel Sambuc "Cannot have more than one UDP transport");
41011be35a1SLionel Sambuc goto error;
41111be35a1SLionel Sambuc }
41211be35a1SLionel Sambuc udptrans = strdup(nconf->nc_netid);
41311be35a1SLionel Sambuc if (udptrans == NULL) {
41411be35a1SLionel Sambuc free(pml);
41511be35a1SLionel Sambuc warn("Cannot allocate memory");
41611be35a1SLionel Sambuc goto error;
41711be35a1SLionel Sambuc }
41811be35a1SLionel Sambuc pml->pml_map.pm_prot = IPPROTO_UDP;
41911be35a1SLionel Sambuc
42011be35a1SLionel Sambuc /* Let's snarf the universal address */
42111be35a1SLionel Sambuc /* "h1.h2.h3.h4.p1.p2" */
42211be35a1SLionel Sambuc udp_uaddr = taddr2uaddr(nconf, &taddr.addr);
42311be35a1SLionel Sambuc }
42411be35a1SLionel Sambuc pml->pml_next = list_pml;
42511be35a1SLionel Sambuc list_pml = pml;
42611be35a1SLionel Sambuc
42711be35a1SLionel Sambuc /* Add version 3 information */
42811be35a1SLionel Sambuc pml = malloc(sizeof (struct pmaplist));
42911be35a1SLionel Sambuc if (pml == NULL) {
43011be35a1SLionel Sambuc warn("Cannot allocate memory");
43111be35a1SLionel Sambuc goto error;
43211be35a1SLionel Sambuc }
43311be35a1SLionel Sambuc pml->pml_map = list_pml->pml_map;
43411be35a1SLionel Sambuc pml->pml_map.pm_vers = RPCBVERS;
43511be35a1SLionel Sambuc pml->pml_next = list_pml;
43611be35a1SLionel Sambuc list_pml = pml;
43711be35a1SLionel Sambuc
43811be35a1SLionel Sambuc /* Add version 4 information */
43911be35a1SLionel Sambuc pml = malloc(sizeof (struct pmaplist));
44011be35a1SLionel Sambuc if (pml == NULL) {
44111be35a1SLionel Sambuc warn("Cannot allocate memory");
44211be35a1SLionel Sambuc goto error;
44311be35a1SLionel Sambuc }
44411be35a1SLionel Sambuc pml->pml_map = list_pml->pml_map;
44511be35a1SLionel Sambuc pml->pml_map.pm_vers = RPCBVERS4;
44611be35a1SLionel Sambuc pml->pml_next = list_pml;
44711be35a1SLionel Sambuc list_pml = pml;
44811be35a1SLionel Sambuc
44911be35a1SLionel Sambuc /* Also add version 2 stuff to rpcbind list */
45011be35a1SLionel Sambuc rbllist_add(PMAPPROG, PMAPVERS, nconf, &taddr.addr);
45111be35a1SLionel Sambuc }
45211be35a1SLionel Sambuc #endif
45311be35a1SLionel Sambuc
45411be35a1SLionel Sambuc /* version 3 registration */
45511be35a1SLionel Sambuc if (!svc_reg(my_xprt, RPCBPROG, RPCBVERS, rpcb_service_3, NULL)) {
45611be35a1SLionel Sambuc warn("Could not register %s version 3", nconf->nc_netid);
45711be35a1SLionel Sambuc goto error;
45811be35a1SLionel Sambuc }
45911be35a1SLionel Sambuc rbllist_add(RPCBPROG, RPCBVERS, nconf, &taddr.addr);
46011be35a1SLionel Sambuc
46111be35a1SLionel Sambuc /* version 4 registration */
46211be35a1SLionel Sambuc if (!svc_reg(my_xprt, RPCBPROG, RPCBVERS4, rpcb_service_4, NULL)) {
46311be35a1SLionel Sambuc warn("Could not register %s version 4", nconf->nc_netid);
46411be35a1SLionel Sambuc goto error;
46511be35a1SLionel Sambuc }
46611be35a1SLionel Sambuc rbllist_add(RPCBPROG, RPCBVERS4, nconf, &taddr.addr);
46711be35a1SLionel Sambuc
46811be35a1SLionel Sambuc /* decide if bound checking works for this transport */
46911be35a1SLionel Sambuc status = add_bndlist(nconf, &taddr.addr);
47011be35a1SLionel Sambuc #ifdef RPCBIND_DEBUG
47111be35a1SLionel Sambuc if (debugging) {
47211be35a1SLionel Sambuc if (status < 0) {
47311be35a1SLionel Sambuc fprintf(stderr, "Error in finding bind status for %s\n",
47411be35a1SLionel Sambuc nconf->nc_netid);
47511be35a1SLionel Sambuc } else if (status == 0) {
47611be35a1SLionel Sambuc fprintf(stderr, "check binding for %s\n",
47711be35a1SLionel Sambuc nconf->nc_netid);
47811be35a1SLionel Sambuc } else if (status > 0) {
47911be35a1SLionel Sambuc fprintf(stderr, "No check binding for %s\n",
48011be35a1SLionel Sambuc nconf->nc_netid);
48111be35a1SLionel Sambuc }
48211be35a1SLionel Sambuc }
48384d9c625SLionel Sambuc #else
48484d9c625SLionel Sambuc __USE(status);
48511be35a1SLionel Sambuc #endif
48611be35a1SLionel Sambuc /*
48711be35a1SLionel Sambuc * rmtcall only supported on CLTS transports for now.
48811be35a1SLionel Sambuc */
48911be35a1SLionel Sambuc if (nconf->nc_semantics == NC_TPI_CLTS) {
49011be35a1SLionel Sambuc status = create_rmtcall_fd(nconf);
49111be35a1SLionel Sambuc
49211be35a1SLionel Sambuc #ifdef RPCBIND_DEBUG
49311be35a1SLionel Sambuc if (debugging) {
49411be35a1SLionel Sambuc if (status < 0) {
49511be35a1SLionel Sambuc fprintf(stderr,
49611be35a1SLionel Sambuc "Could not create rmtcall fd for %s\n",
49711be35a1SLionel Sambuc nconf->nc_netid);
49811be35a1SLionel Sambuc } else {
49911be35a1SLionel Sambuc fprintf(stderr, "rmtcall fd for %s is %d\n",
50011be35a1SLionel Sambuc nconf->nc_netid, status);
50111be35a1SLionel Sambuc }
50211be35a1SLionel Sambuc }
50311be35a1SLionel Sambuc #endif
50411be35a1SLionel Sambuc }
50511be35a1SLionel Sambuc return (0);
50611be35a1SLionel Sambuc error:
50711be35a1SLionel Sambuc (void)rump_sys_close(fd);
50811be35a1SLionel Sambuc return (1);
50911be35a1SLionel Sambuc }
51011be35a1SLionel Sambuc
51111be35a1SLionel Sambuc static void
rbllist_add(rpcprog_t prog,rpcvers_t vers,struct netconfig * nconf,struct netbuf * addr)51211be35a1SLionel Sambuc rbllist_add(rpcprog_t prog, rpcvers_t vers, struct netconfig *nconf,
51311be35a1SLionel Sambuc struct netbuf *addr)
51411be35a1SLionel Sambuc {
51511be35a1SLionel Sambuc rpcblist_ptr rbl;
51611be35a1SLionel Sambuc
51711be35a1SLionel Sambuc rbl = malloc(sizeof(rpcblist));
51811be35a1SLionel Sambuc if (rbl == NULL) {
51911be35a1SLionel Sambuc warn("Out of memory");
52011be35a1SLionel Sambuc return;
52111be35a1SLionel Sambuc }
52211be35a1SLionel Sambuc
52311be35a1SLionel Sambuc rbl->rpcb_map.r_prog = prog;
52411be35a1SLionel Sambuc rbl->rpcb_map.r_vers = vers;
52511be35a1SLionel Sambuc rbl->rpcb_map.r_netid = strdup(nconf->nc_netid);
52611be35a1SLionel Sambuc rbl->rpcb_map.r_addr = taddr2uaddr(nconf, addr);
52711be35a1SLionel Sambuc rbl->rpcb_map.r_owner = strdup(rpcbind_superuser);
52811be35a1SLionel Sambuc rbl->rpcb_next = list_rbl; /* Attach to global list */
52911be35a1SLionel Sambuc list_rbl = rbl;
53011be35a1SLionel Sambuc }
53111be35a1SLionel Sambuc
53211be35a1SLionel Sambuc /*
53311be35a1SLionel Sambuc * Catch the signal and die
53411be35a1SLionel Sambuc */
53511be35a1SLionel Sambuc static void
terminate(int dummy)53611be35a1SLionel Sambuc terminate(int dummy)
53711be35a1SLionel Sambuc {
53811be35a1SLionel Sambuc #ifdef WARMSTART
53911be35a1SLionel Sambuc syslog(LOG_ERR,
54011be35a1SLionel Sambuc "rpcbind terminating on signal. Restart with \"rpcbind -w\"");
54111be35a1SLionel Sambuc write_warmstart(); /* Dump yourself */
54211be35a1SLionel Sambuc #endif
54311be35a1SLionel Sambuc exit(2);
54411be35a1SLionel Sambuc }
54511be35a1SLionel Sambuc
54611be35a1SLionel Sambuc void
rpcbind_abort()54711be35a1SLionel Sambuc rpcbind_abort()
54811be35a1SLionel Sambuc {
54911be35a1SLionel Sambuc #ifdef WARMSTART
55011be35a1SLionel Sambuc write_warmstart(); /* Dump yourself */
55111be35a1SLionel Sambuc #endif
55211be35a1SLionel Sambuc abort();
55311be35a1SLionel Sambuc }
55411be35a1SLionel Sambuc
55511be35a1SLionel Sambuc #if 0
55611be35a1SLionel Sambuc /* get command line options */
55711be35a1SLionel Sambuc static void
55811be35a1SLionel Sambuc parseargs(int argc, char *argv[])
55911be35a1SLionel Sambuc {
56011be35a1SLionel Sambuc int c;
56111be35a1SLionel Sambuc
56211be35a1SLionel Sambuc while ((c = getopt(argc, argv, "dwailLs")) != -1) {
56311be35a1SLionel Sambuc switch (c) {
56411be35a1SLionel Sambuc case 'a':
56511be35a1SLionel Sambuc doabort = 1; /* when debugging, do an abort on */
56611be35a1SLionel Sambuc break; /* errors; for rpcbind developers */
56711be35a1SLionel Sambuc /* only! */
56811be35a1SLionel Sambuc case 'd':
56911be35a1SLionel Sambuc debugging = 1;
57011be35a1SLionel Sambuc break;
57111be35a1SLionel Sambuc case 'i':
57211be35a1SLionel Sambuc insecure = 1;
57311be35a1SLionel Sambuc break;
57411be35a1SLionel Sambuc case 'L':
57511be35a1SLionel Sambuc oldstyle_local = 1;
57611be35a1SLionel Sambuc break;
57711be35a1SLionel Sambuc case 'l':
57811be35a1SLionel Sambuc verboselog = 1;
57911be35a1SLionel Sambuc break;
58011be35a1SLionel Sambuc case 's':
58111be35a1SLionel Sambuc runasdaemon = 1;
58211be35a1SLionel Sambuc break;
58311be35a1SLionel Sambuc #ifdef WARMSTART
58411be35a1SLionel Sambuc case 'w':
58511be35a1SLionel Sambuc warmstart = 1;
58611be35a1SLionel Sambuc break;
58711be35a1SLionel Sambuc #endif
58811be35a1SLionel Sambuc default: /* error */
58911be35a1SLionel Sambuc fprintf(stderr, "usage: rpcbind [-Idwils]\n");
59011be35a1SLionel Sambuc exit (1);
59111be35a1SLionel Sambuc }
59211be35a1SLionel Sambuc }
59311be35a1SLionel Sambuc if (doabort && !debugging) {
59411be35a1SLionel Sambuc fprintf(stderr,
59511be35a1SLionel Sambuc "-a (abort) specified without -d (debugging) -- ignored.\n");
59611be35a1SLionel Sambuc doabort = 0;
59711be35a1SLionel Sambuc }
59811be35a1SLionel Sambuc }
59911be35a1SLionel Sambuc #endif
60011be35a1SLionel Sambuc
60111be35a1SLionel Sambuc void
reap(int dummy)60211be35a1SLionel Sambuc reap(int dummy)
60311be35a1SLionel Sambuc {
60411be35a1SLionel Sambuc int save_errno = errno;
60511be35a1SLionel Sambuc
60611be35a1SLionel Sambuc while (wait3(NULL, WNOHANG, NULL) > 0)
60711be35a1SLionel Sambuc ;
60811be35a1SLionel Sambuc errno = save_errno;
60911be35a1SLionel Sambuc }
61011be35a1SLionel Sambuc
61111be35a1SLionel Sambuc void
toggle_verboselog(int dummy)61211be35a1SLionel Sambuc toggle_verboselog(int dummy)
61311be35a1SLionel Sambuc {
61411be35a1SLionel Sambuc verboselog = !verboselog;
61511be35a1SLionel Sambuc }
616