14945c132SAlfred Perlstein /* $NetBSD: lockd.c,v 1.7 2000/08/12 18:08:44 thorpej Exp $ */ 24945c132SAlfred Perlstein /* $FreeBSD$ */ 34945c132SAlfred Perlstein 44945c132SAlfred Perlstein /* 54945c132SAlfred Perlstein * Copyright (c) 1995 64945c132SAlfred Perlstein * A.R. Gordon (andrew.gordon@net-tel.co.uk). All rights reserved. 74945c132SAlfred Perlstein * 84945c132SAlfred Perlstein * Redistribution and use in source and binary forms, with or without 94945c132SAlfred Perlstein * modification, are permitted provided that the following conditions 104945c132SAlfred Perlstein * are met: 114945c132SAlfred Perlstein * 1. Redistributions of source code must retain the above copyright 124945c132SAlfred Perlstein * notice, this list of conditions and the following disclaimer. 134945c132SAlfred Perlstein * 2. Redistributions in binary form must reproduce the above copyright 144945c132SAlfred Perlstein * notice, this list of conditions and the following disclaimer in the 154945c132SAlfred Perlstein * documentation and/or other materials provided with the distribution. 164945c132SAlfred Perlstein * 3. All advertising materials mentioning features or use of this software 174945c132SAlfred Perlstein * must display the following acknowledgement: 184945c132SAlfred Perlstein * This product includes software developed for the FreeBSD project 194945c132SAlfred Perlstein * 4. Neither the name of the author nor the names of any co-contributors 204945c132SAlfred Perlstein * may be used to endorse or promote products derived from this software 214945c132SAlfred Perlstein * without specific prior written permission. 224945c132SAlfred Perlstein * 234945c132SAlfred Perlstein * THIS SOFTWARE IS PROVIDED BY ANDREW GORDON AND CONTRIBUTORS ``AS IS'' AND 244945c132SAlfred Perlstein * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 254945c132SAlfred Perlstein * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 264945c132SAlfred Perlstein * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 274945c132SAlfred Perlstein * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 284945c132SAlfred Perlstein * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 294945c132SAlfred Perlstein * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 304945c132SAlfred Perlstein * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 314945c132SAlfred Perlstein * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 324945c132SAlfred Perlstein * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 334945c132SAlfred Perlstein * SUCH DAMAGE. 344945c132SAlfred Perlstein * 354945c132SAlfred Perlstein */ 364945c132SAlfred Perlstein 374945c132SAlfred Perlstein #include <sys/cdefs.h> 384945c132SAlfred Perlstein #ifndef lint 394945c132SAlfred Perlstein __RCSID("$NetBSD: lockd.c,v 1.7 2000/08/12 18:08:44 thorpej Exp $"); 404945c132SAlfred Perlstein #endif 414945c132SAlfred Perlstein 424945c132SAlfred Perlstein /* 434945c132SAlfred Perlstein * main() function for NFS lock daemon. Most of the code in this 444945c132SAlfred Perlstein * file was generated by running rpcgen /usr/include/rpcsvc/nlm_prot.x. 454945c132SAlfred Perlstein * 464945c132SAlfred Perlstein * The actual program logic is in the file lock_proc.c 474945c132SAlfred Perlstein */ 484945c132SAlfred Perlstein 494945c132SAlfred Perlstein #include <sys/types.h> 504945c132SAlfred Perlstein #include <sys/socket.h> 51dfdcada3SDoug Rabson #include <sys/stat.h> 524945c132SAlfred Perlstein 53e56fbc5aSMatteo Riondato #include <netinet/in.h> 54e56fbc5aSMatteo Riondato #include <arpa/inet.h> 55e56fbc5aSMatteo Riondato 564945c132SAlfred Perlstein #include <err.h> 574945c132SAlfred Perlstein #include <stdio.h> 584945c132SAlfred Perlstein #include <stdlib.h> 594945c132SAlfred Perlstein #include <errno.h> 604945c132SAlfred Perlstein #include <syslog.h> 614945c132SAlfred Perlstein #include <signal.h> 624945c132SAlfred Perlstein #include <string.h> 634945c132SAlfred Perlstein #include <unistd.h> 644945c132SAlfred Perlstein #include <libutil.h> 654945c132SAlfred Perlstein #include <netconfig.h> 66e56fbc5aSMatteo Riondato #include <netdb.h> 674945c132SAlfred Perlstein 684945c132SAlfred Perlstein #include <rpc/rpc.h> 69bcb53b16SMartin Blapp #include <rpc/rpc_com.h> 704945c132SAlfred Perlstein #include <rpcsvc/sm_inter.h> 714945c132SAlfred Perlstein 724945c132SAlfred Perlstein #include "lockd.h" 734945c132SAlfred Perlstein #include <rpcsvc/nlm_prot.h> 744945c132SAlfred Perlstein 754945c132SAlfred Perlstein int debug_level = 0; /* 0 = no debugging syslog() calls */ 764945c132SAlfred Perlstein int _rpcsvcdirty = 0; 774945c132SAlfred Perlstein 784945c132SAlfred Perlstein int grace_expired; 794945c132SAlfred Perlstein int nsm_state; 80dfdcada3SDoug Rabson int kernel_lockd; 814945c132SAlfred Perlstein pid_t client_pid; 824945c132SAlfred Perlstein struct mon mon_host; 83e56fbc5aSMatteo Riondato char **hosts, *svcport_str = NULL; 84e56fbc5aSMatteo Riondato int nhosts = 0; 85e56fbc5aSMatteo Riondato int xcreated = 0; 86dfdcada3SDoug Rabson char **addrs; /* actually (netid, uaddr) pairs */ 87dfdcada3SDoug Rabson int naddrs; /* count of how many (netid, uaddr) pairs */ 884945c132SAlfred Perlstein 89e56fbc5aSMatteo Riondato void create_service(struct netconfig *nconf); 90dfdcada3SDoug Rabson void lookup_addresses(struct netconfig *nconf); 914945c132SAlfred Perlstein void init_nsm(void); 9233314abeSAlfred Perlstein void nlm_prog_0(struct svc_req *, SVCXPRT *); 9333314abeSAlfred Perlstein void nlm_prog_1(struct svc_req *, SVCXPRT *); 9433314abeSAlfred Perlstein void nlm_prog_3(struct svc_req *, SVCXPRT *); 9533314abeSAlfred Perlstein void nlm_prog_4(struct svc_req *, SVCXPRT *); 96e56fbc5aSMatteo Riondato void out_of_mem(void); 9733314abeSAlfred Perlstein void usage(void); 984945c132SAlfred Perlstein 9933314abeSAlfred Perlstein void sigalarm_handler(void); 1004945c132SAlfred Perlstein 101dfdcada3SDoug Rabson /* 102dfdcada3SDoug Rabson * XXX move to some header file. 103dfdcada3SDoug Rabson */ 104dfdcada3SDoug Rabson #define _PATH_RPCLOCKDSOCK "/var/run/rpclockd.sock" 105dfdcada3SDoug Rabson 1064945c132SAlfred Perlstein int 107e56fbc5aSMatteo Riondato main(int argc, char **argv) 1084945c132SAlfred Perlstein { 109e56fbc5aSMatteo Riondato int ch, i, s; 110e56fbc5aSMatteo Riondato void *nc_handle; 111e56fbc5aSMatteo Riondato char *endptr, **hosts_bak; 1124945c132SAlfred Perlstein struct sigaction sigalarm; 1134945c132SAlfred Perlstein int grace_period = 30; 1144945c132SAlfred Perlstein struct netconfig *nconf; 115e56fbc5aSMatteo Riondato int have_v6 = 1; 116bcb53b16SMartin Blapp int maxrec = RPC_MAXDATASIZE; 11769f129c9SMatteo Riondato in_port_t svcport = 0; 1184945c132SAlfred Perlstein 119dfdcada3SDoug Rabson while ((ch = getopt(argc, argv, "d:g:h:kp:")) != (-1)) { 1204945c132SAlfred Perlstein switch (ch) { 1214945c132SAlfred Perlstein case 'd': 1224945c132SAlfred Perlstein debug_level = atoi(optarg); 1234945c132SAlfred Perlstein if (!debug_level) { 1244945c132SAlfred Perlstein usage(); 1254945c132SAlfred Perlstein /* NOTREACHED */ 1264945c132SAlfred Perlstein } 1274945c132SAlfred Perlstein break; 1284945c132SAlfred Perlstein case 'g': 1294945c132SAlfred Perlstein grace_period = atoi(optarg); 1304945c132SAlfred Perlstein if (!grace_period) { 1314945c132SAlfred Perlstein usage(); 1324945c132SAlfred Perlstein /* NOTREACHED */ 1334945c132SAlfred Perlstein } 1344945c132SAlfred Perlstein break; 135e56fbc5aSMatteo Riondato case 'h': 136e56fbc5aSMatteo Riondato ++nhosts; 137e56fbc5aSMatteo Riondato hosts_bak = hosts; 138e56fbc5aSMatteo Riondato hosts_bak = realloc(hosts, nhosts * sizeof(char *)); 139e56fbc5aSMatteo Riondato if (hosts_bak == NULL) { 140e56fbc5aSMatteo Riondato if (hosts != NULL) { 141e56fbc5aSMatteo Riondato for (i = 0; i < nhosts; i++) 142e56fbc5aSMatteo Riondato free(hosts[i]); 143e56fbc5aSMatteo Riondato free(hosts); 144e56fbc5aSMatteo Riondato out_of_mem(); 145e56fbc5aSMatteo Riondato } 146e56fbc5aSMatteo Riondato } 147e56fbc5aSMatteo Riondato hosts = hosts_bak; 148e56fbc5aSMatteo Riondato hosts[nhosts - 1] = strdup(optarg); 149e56fbc5aSMatteo Riondato if (hosts[nhosts - 1] == NULL) { 150e56fbc5aSMatteo Riondato for (i = 0; i < (nhosts - 1); i++) 151e56fbc5aSMatteo Riondato free(hosts[i]); 152e56fbc5aSMatteo Riondato free(hosts); 153e56fbc5aSMatteo Riondato out_of_mem(); 154e56fbc5aSMatteo Riondato } 155e56fbc5aSMatteo Riondato break; 156dfdcada3SDoug Rabson case 'k': 157dfdcada3SDoug Rabson kernel_lockd = TRUE; 158dfdcada3SDoug Rabson break; 15969f129c9SMatteo Riondato case 'p': 16069f129c9SMatteo Riondato endptr = NULL; 16169f129c9SMatteo Riondato svcport = (in_port_t)strtoul(optarg, &endptr, 10); 16269f129c9SMatteo Riondato if (endptr == NULL || *endptr != '\0' || 16369f129c9SMatteo Riondato svcport == 0 || svcport >= IPPORT_MAX) 16469f129c9SMatteo Riondato usage(); 165e56fbc5aSMatteo Riondato svcport_str = strdup(optarg); 16669f129c9SMatteo Riondato break; 1674945c132SAlfred Perlstein default: 1684945c132SAlfred Perlstein case '?': 1694945c132SAlfred Perlstein usage(); 1704945c132SAlfred Perlstein /* NOTREACHED */ 1714945c132SAlfred Perlstein } 1724945c132SAlfred Perlstein } 1734945c132SAlfred Perlstein if (geteuid()) { /* This command allowed only to root */ 1744945c132SAlfred Perlstein fprintf(stderr, "Sorry. You are not superuser\n"); 1754945c132SAlfred Perlstein exit(1); 1764945c132SAlfred Perlstein } 1774945c132SAlfred Perlstein 1784945c132SAlfred Perlstein (void)rpcb_unset(NLM_PROG, NLM_SM, NULL); 1794945c132SAlfred Perlstein (void)rpcb_unset(NLM_PROG, NLM_VERS, NULL); 1804945c132SAlfred Perlstein (void)rpcb_unset(NLM_PROG, NLM_VERSX, NULL); 1814945c132SAlfred Perlstein (void)rpcb_unset(NLM_PROG, NLM_VERS4, NULL); 1824945c132SAlfred Perlstein 1834945c132SAlfred Perlstein /* 1844945c132SAlfred Perlstein * Check if IPv6 support is present. 1854945c132SAlfred Perlstein */ 1864945c132SAlfred Perlstein s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); 1874945c132SAlfred Perlstein if (s < 0) 188e56fbc5aSMatteo Riondato have_v6 = 0; 189e56fbc5aSMatteo Riondato else 1904945c132SAlfred Perlstein close(s); 19169f129c9SMatteo Riondato 192bcb53b16SMartin Blapp rpc_control(RPC_SVC_CONNMAXREC_SET, &maxrec); 193bcb53b16SMartin Blapp 194e56fbc5aSMatteo Riondato /* 195e56fbc5aSMatteo Riondato * If no hosts were specified, add a wildcard entry to bind to 196e56fbc5aSMatteo Riondato * INADDR_ANY. Otherwise make sure 127.0.0.1 and ::1 are added to the 197e56fbc5aSMatteo Riondato * list. 198e56fbc5aSMatteo Riondato */ 199e56fbc5aSMatteo Riondato if (nhosts == 0) { 200e56fbc5aSMatteo Riondato hosts = malloc(sizeof(char**)); 201e56fbc5aSMatteo Riondato if (hosts == NULL) 202e56fbc5aSMatteo Riondato out_of_mem(); 2034945c132SAlfred Perlstein 204e56fbc5aSMatteo Riondato hosts[0] = "*"; 205e56fbc5aSMatteo Riondato nhosts = 1; 20669f129c9SMatteo Riondato } else { 207e56fbc5aSMatteo Riondato hosts_bak = hosts; 208e56fbc5aSMatteo Riondato if (have_v6) { 209e56fbc5aSMatteo Riondato hosts_bak = realloc(hosts, (nhosts + 2) * 210e56fbc5aSMatteo Riondato sizeof(char *)); 211e56fbc5aSMatteo Riondato if (hosts_bak == NULL) { 212e56fbc5aSMatteo Riondato for (i = 0; i < nhosts; i++) 213e56fbc5aSMatteo Riondato free(hosts[i]); 214e56fbc5aSMatteo Riondato free(hosts); 215e56fbc5aSMatteo Riondato out_of_mem(); 216e56fbc5aSMatteo Riondato } else 217e56fbc5aSMatteo Riondato hosts = hosts_bak; 218e56fbc5aSMatteo Riondato 219e56fbc5aSMatteo Riondato nhosts += 2; 220e56fbc5aSMatteo Riondato hosts[nhosts - 2] = "::1"; 221e56fbc5aSMatteo Riondato } else { 222e56fbc5aSMatteo Riondato hosts_bak = realloc(hosts, (nhosts + 1) * sizeof(char *)); 223e56fbc5aSMatteo Riondato if (hosts_bak == NULL) { 224e56fbc5aSMatteo Riondato for (i = 0; i < nhosts; i++) 225e56fbc5aSMatteo Riondato free(hosts[i]); 226e56fbc5aSMatteo Riondato 227e56fbc5aSMatteo Riondato free(hosts); 228e56fbc5aSMatteo Riondato out_of_mem(); 229e56fbc5aSMatteo Riondato } else { 230e56fbc5aSMatteo Riondato nhosts += 1; 231e56fbc5aSMatteo Riondato hosts = hosts_bak; 232e56fbc5aSMatteo Riondato } 233e56fbc5aSMatteo Riondato } 234e56fbc5aSMatteo Riondato hosts[nhosts - 1] = "127.0.0.1"; 23569f129c9SMatteo Riondato } 23669f129c9SMatteo Riondato 237dfdcada3SDoug Rabson if (kernel_lockd) { 238dfdcada3SDoug Rabson /* 239dfdcada3SDoug Rabson * For the kernel lockd case, we run a cut-down RPC 240dfdcada3SDoug Rabson * service on a local-domain socket. The kernel's RPC 241dfdcada3SDoug Rabson * server will pass what it can't handle (mainly 242dfdcada3SDoug Rabson * client replies) down to us. This can go away 243dfdcada3SDoug Rabson * entirely if/when we move the client side of NFS 244dfdcada3SDoug Rabson * locking into the kernel. 245dfdcada3SDoug Rabson */ 246dfdcada3SDoug Rabson struct sockaddr_un sun; 247dfdcada3SDoug Rabson int fd, oldmask; 248dfdcada3SDoug Rabson SVCXPRT *xprt; 249dfdcada3SDoug Rabson 250dfdcada3SDoug Rabson memset(&sun, 0, sizeof sun); 251dfdcada3SDoug Rabson sun.sun_family = AF_LOCAL; 252dfdcada3SDoug Rabson unlink(_PATH_RPCLOCKDSOCK); 253dfdcada3SDoug Rabson strcpy(sun.sun_path, _PATH_RPCLOCKDSOCK); 254dfdcada3SDoug Rabson sun.sun_len = SUN_LEN(&sun); 255dfdcada3SDoug Rabson fd = socket(AF_LOCAL, SOCK_STREAM, 0); 256dfdcada3SDoug Rabson if (!fd) { 257dfdcada3SDoug Rabson err(1, "Can't create local lockd socket"); 258dfdcada3SDoug Rabson } 259dfdcada3SDoug Rabson oldmask = umask(S_IXUSR|S_IRWXG|S_IRWXO); 260dfdcada3SDoug Rabson if (bind(fd, (struct sockaddr *) &sun, sun.sun_len) < 0) { 261dfdcada3SDoug Rabson err(1, "Can't bind local lockd socket"); 262dfdcada3SDoug Rabson } 263dfdcada3SDoug Rabson umask(oldmask); 264dfdcada3SDoug Rabson if (listen(fd, SOMAXCONN) < 0) { 265dfdcada3SDoug Rabson err(1, "Can't listen on local lockd socket"); 266dfdcada3SDoug Rabson } 267dfdcada3SDoug Rabson xprt = svc_vc_create(fd, RPC_MAXDATASIZE, RPC_MAXDATASIZE); 268dfdcada3SDoug Rabson if (!xprt) { 269dfdcada3SDoug Rabson err(1, "Can't create transport for local lockd socket"); 270dfdcada3SDoug Rabson } 271dfdcada3SDoug Rabson if (!svc_reg(xprt, NLM_PROG, NLM_VERS4, nlm_prog_4, NULL)) { 272dfdcada3SDoug Rabson err(1, "Can't register service for local lockd socket"); 273dfdcada3SDoug Rabson } 274dfdcada3SDoug Rabson 275dfdcada3SDoug Rabson /* 276dfdcada3SDoug Rabson * We need to look up the addresses so that we can 277dfdcada3SDoug Rabson * hand uaddrs (ascii encoded address+port strings) to 278dfdcada3SDoug Rabson * the kernel. 279dfdcada3SDoug Rabson */ 280dfdcada3SDoug Rabson nc_handle = setnetconfig(); 281dfdcada3SDoug Rabson while ((nconf = getnetconfig(nc_handle))) { 282dfdcada3SDoug Rabson /* We want to listen only on udp6, tcp6, udp, tcp transports */ 283dfdcada3SDoug Rabson if (nconf->nc_flag & NC_VISIBLE) { 284dfdcada3SDoug Rabson /* Skip if there's no IPv6 support */ 285dfdcada3SDoug Rabson if (have_v6 == 0 && strcmp(nconf->nc_protofmly, "inet6") == 0) { 286dfdcada3SDoug Rabson /* DO NOTHING */ 287dfdcada3SDoug Rabson } else { 288dfdcada3SDoug Rabson lookup_addresses(nconf); 289dfdcada3SDoug Rabson } 290dfdcada3SDoug Rabson } 291dfdcada3SDoug Rabson } 292dfdcada3SDoug Rabson endnetconfig(nc_handle); 293dfdcada3SDoug Rabson } else { 294e56fbc5aSMatteo Riondato nc_handle = setnetconfig(); 295e56fbc5aSMatteo Riondato while ((nconf = getnetconfig(nc_handle))) { 296e56fbc5aSMatteo Riondato /* We want to listen only on udp6, tcp6, udp, tcp transports */ 297e56fbc5aSMatteo Riondato if (nconf->nc_flag & NC_VISIBLE) { 298e56fbc5aSMatteo Riondato /* Skip if there's no IPv6 support */ 299e56fbc5aSMatteo Riondato if (have_v6 == 0 && strcmp(nconf->nc_protofmly, "inet6") == 0) { 300e56fbc5aSMatteo Riondato /* DO NOTHING */ 301e56fbc5aSMatteo Riondato } else { 302e56fbc5aSMatteo Riondato create_service(nconf); 3034945c132SAlfred Perlstein } 3044945c132SAlfred Perlstein } 3054945c132SAlfred Perlstein } 306e56fbc5aSMatteo Riondato endnetconfig(nc_handle); 307dfdcada3SDoug Rabson } 3084945c132SAlfred Perlstein 3094945c132SAlfred Perlstein /* 3104945c132SAlfred Perlstein * Note that it is NOT sensible to run this program from inetd - the 3114945c132SAlfred Perlstein * protocol assumes that it will run immediately at boot time. 3124945c132SAlfred Perlstein */ 3133d81d1adSMichael Reifenberger if (daemon(0, debug_level > 0)) { 3144945c132SAlfred Perlstein err(1, "cannot fork"); 3154945c132SAlfred Perlstein /* NOTREACHED */ 3164945c132SAlfred Perlstein } 3174945c132SAlfred Perlstein 3184945c132SAlfred Perlstein openlog("rpc.lockd", 0, LOG_DAEMON); 3194945c132SAlfred Perlstein if (debug_level) 3204945c132SAlfred Perlstein syslog(LOG_INFO, "Starting, debug level %d", debug_level); 3214945c132SAlfred Perlstein else 3224945c132SAlfred Perlstein syslog(LOG_INFO, "Starting"); 3234945c132SAlfred Perlstein 3244945c132SAlfred Perlstein sigalarm.sa_handler = (sig_t) sigalarm_handler; 3254945c132SAlfred Perlstein sigemptyset(&sigalarm.sa_mask); 3264945c132SAlfred Perlstein sigalarm.sa_flags = SA_RESETHAND; /* should only happen once */ 3274945c132SAlfred Perlstein sigalarm.sa_flags |= SA_RESTART; 3284945c132SAlfred Perlstein if (sigaction(SIGALRM, &sigalarm, NULL) != 0) { 3294945c132SAlfred Perlstein syslog(LOG_WARNING, "sigaction(SIGALRM) failed: %s", 3304945c132SAlfred Perlstein strerror(errno)); 3314945c132SAlfred Perlstein exit(1); 3324945c132SAlfred Perlstein } 333dfdcada3SDoug Rabson 334dfdcada3SDoug Rabson if (kernel_lockd) { 335dfdcada3SDoug Rabson client_pid = client_request(); 336dfdcada3SDoug Rabson 337dfdcada3SDoug Rabson /* 338dfdcada3SDoug Rabson * Create a child process to enter the kernel and then 339dfdcada3SDoug Rabson * wait for RPCs on our local domain socket. 340dfdcada3SDoug Rabson */ 341dfdcada3SDoug Rabson if (!fork()) 342dfdcada3SDoug Rabson nlm_syscall(debug_level, grace_period, naddrs, addrs); 343dfdcada3SDoug Rabson else 344dfdcada3SDoug Rabson svc_run(); 345dfdcada3SDoug Rabson } else { 3464945c132SAlfred Perlstein grace_expired = 0; 34735a64c9fSThomas Quinot alarm(grace_period); 3484945c132SAlfred Perlstein 3494945c132SAlfred Perlstein init_nsm(); 3504945c132SAlfred Perlstein 3514945c132SAlfred Perlstein client_pid = client_request(); 3524945c132SAlfred Perlstein 3534945c132SAlfred Perlstein svc_run(); /* Should never return */ 354dfdcada3SDoug Rabson } 3554945c132SAlfred Perlstein exit(1); 3564945c132SAlfred Perlstein } 3574945c132SAlfred Perlstein 358e56fbc5aSMatteo Riondato /* 359e56fbc5aSMatteo Riondato * This routine creates and binds sockets on the appropriate 360e56fbc5aSMatteo Riondato * addresses. It gets called one time for each transport and 361e56fbc5aSMatteo Riondato * registrates the service with rpcbind on that trasport. 362e56fbc5aSMatteo Riondato */ 363e56fbc5aSMatteo Riondato void 364e56fbc5aSMatteo Riondato create_service(struct netconfig *nconf) 365e56fbc5aSMatteo Riondato { 366e56fbc5aSMatteo Riondato struct addrinfo hints, *res = NULL; 367e56fbc5aSMatteo Riondato struct sockaddr_in *sin; 368e56fbc5aSMatteo Riondato struct sockaddr_in6 *sin6; 369e56fbc5aSMatteo Riondato struct __rpc_sockinfo si; 370e56fbc5aSMatteo Riondato struct netbuf servaddr; 371e56fbc5aSMatteo Riondato SVCXPRT *transp = NULL; 372e56fbc5aSMatteo Riondato int aicode; 373e56fbc5aSMatteo Riondato int fd; 374e56fbc5aSMatteo Riondato int nhostsbak; 375e56fbc5aSMatteo Riondato int r; 376e56fbc5aSMatteo Riondato int registered = 0; 377e56fbc5aSMatteo Riondato u_int32_t host_addr[4]; /* IPv4 or IPv6 */ 378e56fbc5aSMatteo Riondato 379e56fbc5aSMatteo Riondato if ((nconf->nc_semantics != NC_TPI_CLTS) && 380e56fbc5aSMatteo Riondato (nconf->nc_semantics != NC_TPI_COTS) && 381e56fbc5aSMatteo Riondato (nconf->nc_semantics != NC_TPI_COTS_ORD)) 382e56fbc5aSMatteo Riondato return; /* not my type */ 383e56fbc5aSMatteo Riondato 384e56fbc5aSMatteo Riondato /* 385e56fbc5aSMatteo Riondato * XXX - using RPC library internal functions. 386e56fbc5aSMatteo Riondato */ 387e56fbc5aSMatteo Riondato if (!__rpc_nconf2sockinfo(nconf, &si)) { 388e56fbc5aSMatteo Riondato syslog(LOG_ERR, "cannot get information for %s", 389e56fbc5aSMatteo Riondato nconf->nc_netid); 390e56fbc5aSMatteo Riondato return; 391e56fbc5aSMatteo Riondato } 392e56fbc5aSMatteo Riondato 393e56fbc5aSMatteo Riondato /* Get rpc.statd's address on this transport */ 394e56fbc5aSMatteo Riondato memset(&hints, 0, sizeof hints); 395e56fbc5aSMatteo Riondato hints.ai_flags = AI_PASSIVE; 396e56fbc5aSMatteo Riondato hints.ai_family = si.si_af; 397e56fbc5aSMatteo Riondato hints.ai_socktype = si.si_socktype; 398e56fbc5aSMatteo Riondato hints.ai_protocol = si.si_proto; 399e56fbc5aSMatteo Riondato 400e56fbc5aSMatteo Riondato /* 401e56fbc5aSMatteo Riondato * Bind to specific IPs if asked to 402e56fbc5aSMatteo Riondato */ 403e56fbc5aSMatteo Riondato nhostsbak = nhosts; 404e56fbc5aSMatteo Riondato while (nhostsbak > 0) { 405e56fbc5aSMatteo Riondato --nhostsbak; 406e56fbc5aSMatteo Riondato 407e56fbc5aSMatteo Riondato /* 408e56fbc5aSMatteo Riondato * XXX - using RPC library internal functions. 409e56fbc5aSMatteo Riondato */ 410e56fbc5aSMatteo Riondato if ((fd = __rpc_nconf2fd(nconf)) < 0) { 411e56fbc5aSMatteo Riondato syslog(LOG_ERR, "cannot create socket for %s", 412e56fbc5aSMatteo Riondato nconf->nc_netid); 413e56fbc5aSMatteo Riondato continue; 414e56fbc5aSMatteo Riondato } 415e56fbc5aSMatteo Riondato 416e56fbc5aSMatteo Riondato switch (hints.ai_family) { 417e56fbc5aSMatteo Riondato case AF_INET: 418e56fbc5aSMatteo Riondato if (inet_pton(AF_INET, hosts[nhostsbak], 419e56fbc5aSMatteo Riondato host_addr) == 1) { 420e56fbc5aSMatteo Riondato hints.ai_flags &= AI_NUMERICHOST; 421e56fbc5aSMatteo Riondato } else { 422e56fbc5aSMatteo Riondato /* 423e56fbc5aSMatteo Riondato * Skip if we have an AF_INET6 address. 424e56fbc5aSMatteo Riondato */ 425e56fbc5aSMatteo Riondato if (inet_pton(AF_INET6, hosts[nhostsbak], 426e56fbc5aSMatteo Riondato host_addr) == 1) { 427e56fbc5aSMatteo Riondato close(fd); 428e56fbc5aSMatteo Riondato continue; 429e56fbc5aSMatteo Riondato } 430e56fbc5aSMatteo Riondato } 431e56fbc5aSMatteo Riondato break; 432e56fbc5aSMatteo Riondato case AF_INET6: 433e56fbc5aSMatteo Riondato if (inet_pton(AF_INET6, hosts[nhostsbak], 434e56fbc5aSMatteo Riondato host_addr) == 1) { 435e56fbc5aSMatteo Riondato hints.ai_flags &= AI_NUMERICHOST; 436e56fbc5aSMatteo Riondato } else { 437e56fbc5aSMatteo Riondato /* 438e56fbc5aSMatteo Riondato * Skip if we have an AF_INET address. 439e56fbc5aSMatteo Riondato */ 440e56fbc5aSMatteo Riondato if (inet_pton(AF_INET, hosts[nhostsbak], 441e56fbc5aSMatteo Riondato host_addr) == 1) { 442e56fbc5aSMatteo Riondato close(fd); 443e56fbc5aSMatteo Riondato continue; 444e56fbc5aSMatteo Riondato } 445e56fbc5aSMatteo Riondato } 446e56fbc5aSMatteo Riondato break; 447e56fbc5aSMatteo Riondato default: 448e56fbc5aSMatteo Riondato break; 449e56fbc5aSMatteo Riondato } 450e56fbc5aSMatteo Riondato 451e56fbc5aSMatteo Riondato /* 452e56fbc5aSMatteo Riondato * If no hosts were specified, just bind to INADDR_ANY 453e56fbc5aSMatteo Riondato */ 454e56fbc5aSMatteo Riondato if (strcmp("*", hosts[nhostsbak]) == 0) { 455e56fbc5aSMatteo Riondato if (svcport_str == NULL) { 456e56fbc5aSMatteo Riondato res = malloc(sizeof(struct addrinfo)); 457e56fbc5aSMatteo Riondato if (res == NULL) 458e56fbc5aSMatteo Riondato out_of_mem(); 459e56fbc5aSMatteo Riondato res->ai_flags = hints.ai_flags; 460e56fbc5aSMatteo Riondato res->ai_family = hints.ai_family; 461e56fbc5aSMatteo Riondato res->ai_protocol = hints.ai_protocol; 462e56fbc5aSMatteo Riondato switch (res->ai_family) { 463e56fbc5aSMatteo Riondato case AF_INET: 464e56fbc5aSMatteo Riondato sin = malloc(sizeof(struct sockaddr_in)); 465e56fbc5aSMatteo Riondato if (sin == NULL) 466e56fbc5aSMatteo Riondato out_of_mem(); 467e56fbc5aSMatteo Riondato sin->sin_family = AF_INET; 468e56fbc5aSMatteo Riondato sin->sin_port = htons(0); 469e56fbc5aSMatteo Riondato sin->sin_addr.s_addr = htonl(INADDR_ANY); 470e56fbc5aSMatteo Riondato res->ai_addr = (struct sockaddr*) sin; 471e56fbc5aSMatteo Riondato res->ai_addrlen = (socklen_t) 472e56fbc5aSMatteo Riondato sizeof(res->ai_addr); 473e56fbc5aSMatteo Riondato break; 474e56fbc5aSMatteo Riondato case AF_INET6: 475e56fbc5aSMatteo Riondato sin6 = malloc(sizeof(struct sockaddr_in6)); 47696e460ecSMatteo Riondato if (sin6 == NULL) 477e56fbc5aSMatteo Riondato out_of_mem(); 478e56fbc5aSMatteo Riondato sin6->sin6_family = AF_INET6; 479e56fbc5aSMatteo Riondato sin6->sin6_port = htons(0); 480e56fbc5aSMatteo Riondato sin6->sin6_addr = in6addr_any; 481e56fbc5aSMatteo Riondato res->ai_addr = (struct sockaddr*) sin6; 482e56fbc5aSMatteo Riondato res->ai_addrlen = (socklen_t) sizeof(res->ai_addr); 483e56fbc5aSMatteo Riondato break; 484e56fbc5aSMatteo Riondato default: 485e56fbc5aSMatteo Riondato break; 486e56fbc5aSMatteo Riondato } 487e56fbc5aSMatteo Riondato } else { 488e56fbc5aSMatteo Riondato if ((aicode = getaddrinfo(NULL, svcport_str, 489e56fbc5aSMatteo Riondato &hints, &res)) != 0) { 490e56fbc5aSMatteo Riondato syslog(LOG_ERR, 491e56fbc5aSMatteo Riondato "cannot get local address for %s: %s", 492e56fbc5aSMatteo Riondato nconf->nc_netid, 493e56fbc5aSMatteo Riondato gai_strerror(aicode)); 494e56fbc5aSMatteo Riondato continue; 495e56fbc5aSMatteo Riondato } 496e56fbc5aSMatteo Riondato } 497e56fbc5aSMatteo Riondato } else { 498e56fbc5aSMatteo Riondato if ((aicode = getaddrinfo(hosts[nhostsbak], svcport_str, 499e56fbc5aSMatteo Riondato &hints, &res)) != 0) { 500e56fbc5aSMatteo Riondato syslog(LOG_ERR, 501e56fbc5aSMatteo Riondato "cannot get local address for %s: %s", 502e56fbc5aSMatteo Riondato nconf->nc_netid, gai_strerror(aicode)); 503e56fbc5aSMatteo Riondato continue; 504e56fbc5aSMatteo Riondato } 505e56fbc5aSMatteo Riondato } 506e56fbc5aSMatteo Riondato 507e56fbc5aSMatteo Riondato r = bindresvport_sa(fd, res->ai_addr); 508e56fbc5aSMatteo Riondato if (r != 0) { 509e56fbc5aSMatteo Riondato syslog(LOG_ERR, "bindresvport_sa: %m"); 510e56fbc5aSMatteo Riondato exit(1); 511e56fbc5aSMatteo Riondato } 512e56fbc5aSMatteo Riondato 513e56fbc5aSMatteo Riondato transp = svc_tli_create(fd, nconf, NULL, 514e56fbc5aSMatteo Riondato RPC_MAXDATASIZE, RPC_MAXDATASIZE); 515e56fbc5aSMatteo Riondato 516e56fbc5aSMatteo Riondato if (transp != (SVCXPRT *) NULL) { 517e56fbc5aSMatteo Riondato if (!svc_reg(transp, NLM_PROG, NLM_SM, nlm_prog_0, 518e56fbc5aSMatteo Riondato NULL)) 519e56fbc5aSMatteo Riondato syslog(LOG_ERR, 520e56fbc5aSMatteo Riondato "can't register %s NLM_PROG, NLM_SM service", 521e56fbc5aSMatteo Riondato nconf->nc_netid); 522e56fbc5aSMatteo Riondato 523e56fbc5aSMatteo Riondato if (!svc_reg(transp, NLM_PROG, NLM_VERS, nlm_prog_1, 524e56fbc5aSMatteo Riondato NULL)) 525e56fbc5aSMatteo Riondato syslog(LOG_ERR, 526e56fbc5aSMatteo Riondato "can't register %s NLM_PROG, NLM_VERS service", 527e56fbc5aSMatteo Riondato nconf->nc_netid); 528e56fbc5aSMatteo Riondato 529e56fbc5aSMatteo Riondato if (!svc_reg(transp, NLM_PROG, NLM_VERSX, nlm_prog_3, 530e56fbc5aSMatteo Riondato NULL)) 531e56fbc5aSMatteo Riondato syslog(LOG_ERR, 532e56fbc5aSMatteo Riondato "can't register %s NLM_PROG, NLM_VERSX service", 533e56fbc5aSMatteo Riondato nconf->nc_netid); 534e56fbc5aSMatteo Riondato 535e56fbc5aSMatteo Riondato if (!svc_reg(transp, NLM_PROG, NLM_VERS4, nlm_prog_4, 536e56fbc5aSMatteo Riondato NULL)) 537e56fbc5aSMatteo Riondato syslog(LOG_ERR, 538e56fbc5aSMatteo Riondato "can't register %s NLM_PROG, NLM_VERS4 service", 539e56fbc5aSMatteo Riondato nconf->nc_netid); 540e56fbc5aSMatteo Riondato 541e56fbc5aSMatteo Riondato } else 542e56fbc5aSMatteo Riondato syslog(LOG_WARNING, "can't create %s services", 543e56fbc5aSMatteo Riondato nconf->nc_netid); 544e56fbc5aSMatteo Riondato 545e56fbc5aSMatteo Riondato if (registered == 0) { 546e56fbc5aSMatteo Riondato registered = 1; 547e56fbc5aSMatteo Riondato memset(&hints, 0, sizeof hints); 548e56fbc5aSMatteo Riondato hints.ai_flags = AI_PASSIVE; 549e56fbc5aSMatteo Riondato hints.ai_family = si.si_af; 550e56fbc5aSMatteo Riondato hints.ai_socktype = si.si_socktype; 551e56fbc5aSMatteo Riondato hints.ai_protocol = si.si_proto; 552e56fbc5aSMatteo Riondato 553e56fbc5aSMatteo Riondato if (svcport_str == NULL) { 554e56fbc5aSMatteo Riondato svcport_str = malloc(NI_MAXSERV * sizeof(char)); 555e56fbc5aSMatteo Riondato if (svcport_str == NULL) 556e56fbc5aSMatteo Riondato out_of_mem(); 557e56fbc5aSMatteo Riondato 558e56fbc5aSMatteo Riondato if (getnameinfo(res->ai_addr, 559e56fbc5aSMatteo Riondato res->ai_addr->sa_len, NULL, NI_MAXHOST, 560e56fbc5aSMatteo Riondato svcport_str, NI_MAXSERV * sizeof(char), 561e56fbc5aSMatteo Riondato NI_NUMERICHOST | NI_NUMERICSERV)) 562e56fbc5aSMatteo Riondato errx(1, "Cannot get port number"); 563e56fbc5aSMatteo Riondato } 564e56fbc5aSMatteo Riondato 565e56fbc5aSMatteo Riondato if((aicode = getaddrinfo(NULL, svcport_str, &hints, 566e56fbc5aSMatteo Riondato &res)) != 0) { 567e56fbc5aSMatteo Riondato syslog(LOG_ERR, "cannot get local address: %s", 568e56fbc5aSMatteo Riondato gai_strerror(aicode)); 569e56fbc5aSMatteo Riondato exit(1); 570e56fbc5aSMatteo Riondato } 571e56fbc5aSMatteo Riondato 572e56fbc5aSMatteo Riondato servaddr.buf = malloc(res->ai_addrlen); 573e56fbc5aSMatteo Riondato memcpy(servaddr.buf, res->ai_addr, res->ai_addrlen); 574e56fbc5aSMatteo Riondato servaddr.len = res->ai_addrlen; 575e56fbc5aSMatteo Riondato 576e56fbc5aSMatteo Riondato rpcb_set(NLM_PROG, NLM_SM, nconf, &servaddr); 577e56fbc5aSMatteo Riondato rpcb_set(NLM_PROG, NLM_VERS, nconf, &servaddr); 578e56fbc5aSMatteo Riondato rpcb_set(NLM_PROG, NLM_VERSX, nconf, &servaddr); 579e56fbc5aSMatteo Riondato rpcb_set(NLM_PROG, NLM_VERS4, nconf, &servaddr); 580e56fbc5aSMatteo Riondato 581e56fbc5aSMatteo Riondato xcreated++; 582e56fbc5aSMatteo Riondato freeaddrinfo(res); 583e56fbc5aSMatteo Riondato } 584e56fbc5aSMatteo Riondato } /* end while */ 585e56fbc5aSMatteo Riondato } 586e56fbc5aSMatteo Riondato 587dfdcada3SDoug Rabson /* 588dfdcada3SDoug Rabson * Look up addresses for the kernel to create transports for. 589dfdcada3SDoug Rabson */ 590dfdcada3SDoug Rabson void 591dfdcada3SDoug Rabson lookup_addresses(struct netconfig *nconf) 592dfdcada3SDoug Rabson { 593dfdcada3SDoug Rabson struct addrinfo hints, *res = NULL; 594dfdcada3SDoug Rabson struct sockaddr_in *sin; 595dfdcada3SDoug Rabson struct sockaddr_in6 *sin6; 596dfdcada3SDoug Rabson struct __rpc_sockinfo si; 597dfdcada3SDoug Rabson struct netbuf servaddr; 598dfdcada3SDoug Rabson SVCXPRT *transp = NULL; 599dfdcada3SDoug Rabson int aicode; 600dfdcada3SDoug Rabson int nhostsbak; 601dfdcada3SDoug Rabson int r; 602dfdcada3SDoug Rabson int registered = 0; 603dfdcada3SDoug Rabson u_int32_t host_addr[4]; /* IPv4 or IPv6 */ 604dfdcada3SDoug Rabson char *uaddr; 605dfdcada3SDoug Rabson 606dfdcada3SDoug Rabson if ((nconf->nc_semantics != NC_TPI_CLTS) && 607dfdcada3SDoug Rabson (nconf->nc_semantics != NC_TPI_COTS) && 608dfdcada3SDoug Rabson (nconf->nc_semantics != NC_TPI_COTS_ORD)) 609dfdcada3SDoug Rabson return; /* not my type */ 610dfdcada3SDoug Rabson 611dfdcada3SDoug Rabson /* 612dfdcada3SDoug Rabson * XXX - using RPC library internal functions. 613dfdcada3SDoug Rabson */ 614dfdcada3SDoug Rabson if (!__rpc_nconf2sockinfo(nconf, &si)) { 615dfdcada3SDoug Rabson syslog(LOG_ERR, "cannot get information for %s", 616dfdcada3SDoug Rabson nconf->nc_netid); 617dfdcada3SDoug Rabson return; 618dfdcada3SDoug Rabson } 619dfdcada3SDoug Rabson 620dfdcada3SDoug Rabson /* Get rpc.statd's address on this transport */ 621dfdcada3SDoug Rabson memset(&hints, 0, sizeof hints); 622dfdcada3SDoug Rabson hints.ai_flags = AI_PASSIVE; 623dfdcada3SDoug Rabson hints.ai_family = si.si_af; 624dfdcada3SDoug Rabson hints.ai_socktype = si.si_socktype; 625dfdcada3SDoug Rabson hints.ai_protocol = si.si_proto; 626dfdcada3SDoug Rabson 627dfdcada3SDoug Rabson /* 628dfdcada3SDoug Rabson * Bind to specific IPs if asked to 629dfdcada3SDoug Rabson */ 630dfdcada3SDoug Rabson nhostsbak = nhosts; 631dfdcada3SDoug Rabson while (nhostsbak > 0) { 632dfdcada3SDoug Rabson --nhostsbak; 633dfdcada3SDoug Rabson 634dfdcada3SDoug Rabson switch (hints.ai_family) { 635dfdcada3SDoug Rabson case AF_INET: 636dfdcada3SDoug Rabson if (inet_pton(AF_INET, hosts[nhostsbak], 637dfdcada3SDoug Rabson host_addr) == 1) { 638dfdcada3SDoug Rabson hints.ai_flags &= AI_NUMERICHOST; 639dfdcada3SDoug Rabson } else { 640dfdcada3SDoug Rabson /* 641dfdcada3SDoug Rabson * Skip if we have an AF_INET6 address. 642dfdcada3SDoug Rabson */ 643dfdcada3SDoug Rabson if (inet_pton(AF_INET6, hosts[nhostsbak], 644dfdcada3SDoug Rabson host_addr) == 1) { 645dfdcada3SDoug Rabson continue; 646dfdcada3SDoug Rabson } 647dfdcada3SDoug Rabson } 648dfdcada3SDoug Rabson break; 649dfdcada3SDoug Rabson case AF_INET6: 650dfdcada3SDoug Rabson if (inet_pton(AF_INET6, hosts[nhostsbak], 651dfdcada3SDoug Rabson host_addr) == 1) { 652dfdcada3SDoug Rabson hints.ai_flags &= AI_NUMERICHOST; 653dfdcada3SDoug Rabson } else { 654dfdcada3SDoug Rabson /* 655dfdcada3SDoug Rabson * Skip if we have an AF_INET address. 656dfdcada3SDoug Rabson */ 657dfdcada3SDoug Rabson if (inet_pton(AF_INET, hosts[nhostsbak], 658dfdcada3SDoug Rabson host_addr) == 1) { 659dfdcada3SDoug Rabson continue; 660dfdcada3SDoug Rabson } 661dfdcada3SDoug Rabson } 662dfdcada3SDoug Rabson break; 663dfdcada3SDoug Rabson default: 664dfdcada3SDoug Rabson break; 665dfdcada3SDoug Rabson } 666dfdcada3SDoug Rabson 667dfdcada3SDoug Rabson /* 668dfdcada3SDoug Rabson * If no hosts were specified, just bind to INADDR_ANY 669dfdcada3SDoug Rabson */ 670dfdcada3SDoug Rabson if (strcmp("*", hosts[nhostsbak]) == 0) { 671dfdcada3SDoug Rabson if (svcport_str == NULL) { 672dfdcada3SDoug Rabson res = malloc(sizeof(struct addrinfo)); 673dfdcada3SDoug Rabson if (res == NULL) 674dfdcada3SDoug Rabson out_of_mem(); 675dfdcada3SDoug Rabson res->ai_flags = hints.ai_flags; 676dfdcada3SDoug Rabson res->ai_family = hints.ai_family; 677dfdcada3SDoug Rabson res->ai_protocol = hints.ai_protocol; 678dfdcada3SDoug Rabson switch (res->ai_family) { 679dfdcada3SDoug Rabson case AF_INET: 680dfdcada3SDoug Rabson sin = malloc(sizeof(struct sockaddr_in)); 681dfdcada3SDoug Rabson if (sin == NULL) 682dfdcada3SDoug Rabson out_of_mem(); 683dfdcada3SDoug Rabson sin->sin_family = AF_INET; 684dfdcada3SDoug Rabson sin->sin_port = htons(0); 685dfdcada3SDoug Rabson sin->sin_addr.s_addr = htonl(INADDR_ANY); 686dfdcada3SDoug Rabson res->ai_addr = (struct sockaddr*) sin; 687dfdcada3SDoug Rabson res->ai_addrlen = (socklen_t) 688dfdcada3SDoug Rabson sizeof(res->ai_addr); 689dfdcada3SDoug Rabson break; 690dfdcada3SDoug Rabson case AF_INET6: 691dfdcada3SDoug Rabson sin6 = malloc(sizeof(struct sockaddr_in6)); 692dfdcada3SDoug Rabson if (sin6 == NULL) 693dfdcada3SDoug Rabson out_of_mem(); 694dfdcada3SDoug Rabson sin6->sin6_family = AF_INET6; 695dfdcada3SDoug Rabson sin6->sin6_port = htons(0); 696dfdcada3SDoug Rabson sin6->sin6_addr = in6addr_any; 697dfdcada3SDoug Rabson res->ai_addr = (struct sockaddr*) sin6; 698dfdcada3SDoug Rabson res->ai_addrlen = (socklen_t) sizeof(res->ai_addr); 699dfdcada3SDoug Rabson break; 700dfdcada3SDoug Rabson default: 701dfdcada3SDoug Rabson break; 702dfdcada3SDoug Rabson } 703dfdcada3SDoug Rabson } else { 704dfdcada3SDoug Rabson if ((aicode = getaddrinfo(NULL, svcport_str, 705dfdcada3SDoug Rabson &hints, &res)) != 0) { 706dfdcada3SDoug Rabson syslog(LOG_ERR, 707dfdcada3SDoug Rabson "cannot get local address for %s: %s", 708dfdcada3SDoug Rabson nconf->nc_netid, 709dfdcada3SDoug Rabson gai_strerror(aicode)); 710dfdcada3SDoug Rabson continue; 711dfdcada3SDoug Rabson } 712dfdcada3SDoug Rabson } 713dfdcada3SDoug Rabson } else { 714dfdcada3SDoug Rabson if ((aicode = getaddrinfo(hosts[nhostsbak], svcport_str, 715dfdcada3SDoug Rabson &hints, &res)) != 0) { 716dfdcada3SDoug Rabson syslog(LOG_ERR, 717dfdcada3SDoug Rabson "cannot get local address for %s: %s", 718dfdcada3SDoug Rabson nconf->nc_netid, gai_strerror(aicode)); 719dfdcada3SDoug Rabson continue; 720dfdcada3SDoug Rabson } 721dfdcada3SDoug Rabson } 722dfdcada3SDoug Rabson 723dfdcada3SDoug Rabson servaddr.len = servaddr.maxlen = res->ai_addr->sa_len; 724dfdcada3SDoug Rabson servaddr.buf = res->ai_addr; 725dfdcada3SDoug Rabson uaddr = taddr2uaddr(nconf, &servaddr); 726dfdcada3SDoug Rabson 727dfdcada3SDoug Rabson addrs = realloc(addrs, 2 * (naddrs + 1) * sizeof(char *)); 728dfdcada3SDoug Rabson if (!addrs) 729dfdcada3SDoug Rabson out_of_mem(); 730dfdcada3SDoug Rabson addrs[2 * naddrs] = strdup(nconf->nc_netid); 731dfdcada3SDoug Rabson addrs[2 * naddrs + 1] = uaddr; 732dfdcada3SDoug Rabson naddrs++; 733dfdcada3SDoug Rabson } /* end while */ 734dfdcada3SDoug Rabson } 735dfdcada3SDoug Rabson 7364945c132SAlfred Perlstein void 7374945c132SAlfred Perlstein sigalarm_handler(void) 7384945c132SAlfred Perlstein { 7394945c132SAlfred Perlstein 7404945c132SAlfred Perlstein grace_expired = 1; 7414945c132SAlfred Perlstein } 7424945c132SAlfred Perlstein 7434945c132SAlfred Perlstein void 7444945c132SAlfred Perlstein usage() 7454945c132SAlfred Perlstein { 746dfdcada3SDoug Rabson errx(1, "usage: rpc.lockd [-k] [-d <debuglevel>]" 747e56fbc5aSMatteo Riondato " [-g <grace period>] [-h <bindip>] [-p <port>]"); 7484945c132SAlfred Perlstein } 7494945c132SAlfred Perlstein 7504945c132SAlfred Perlstein /* 7514945c132SAlfred Perlstein * init_nsm -- 7524945c132SAlfred Perlstein * Reset the NSM state-of-the-world and acquire its state. 7534945c132SAlfred Perlstein */ 7544945c132SAlfred Perlstein void 7554945c132SAlfred Perlstein init_nsm(void) 7564945c132SAlfred Perlstein { 7574945c132SAlfred Perlstein enum clnt_stat ret; 7584945c132SAlfred Perlstein my_id id; 7594945c132SAlfred Perlstein sm_stat stat; 760e4b0fedeSAlfred Perlstein char name[] = "NFS NLM"; 761e4b0fedeSAlfred Perlstein char localhost[] = "localhost"; 7624945c132SAlfred Perlstein 7634945c132SAlfred Perlstein /* 7644945c132SAlfred Perlstein * !!! 7654945c132SAlfred Perlstein * The my_id structure isn't used by the SM_UNMON_ALL call, as far 7664945c132SAlfred Perlstein * as I know. Leave it empty for now. 7674945c132SAlfred Perlstein */ 7684945c132SAlfred Perlstein memset(&id, 0, sizeof(id)); 769e4b0fedeSAlfred Perlstein id.my_name = name; 7704945c132SAlfred Perlstein 7714945c132SAlfred Perlstein /* 7724945c132SAlfred Perlstein * !!! 7734945c132SAlfred Perlstein * The statd program must already be registered when lockd runs. 7744945c132SAlfred Perlstein */ 7754945c132SAlfred Perlstein do { 7764945c132SAlfred Perlstein ret = callrpc("localhost", SM_PROG, SM_VERS, SM_UNMON_ALL, 77775e40e46SPeter Wemm (xdrproc_t)xdr_my_id, &id, (xdrproc_t)xdr_sm_stat, &stat); 7784945c132SAlfred Perlstein if (ret == RPC_PROGUNAVAIL) { 7798ebcf97eSGuy Helmer syslog(LOG_WARNING, "%lu %s", SM_PROG, 7808ebcf97eSGuy Helmer clnt_sperrno(ret)); 7814945c132SAlfred Perlstein sleep(2); 7824945c132SAlfred Perlstein continue; 7834945c132SAlfred Perlstein } 7844945c132SAlfred Perlstein break; 7854945c132SAlfred Perlstein } while (0); 7864945c132SAlfred Perlstein 7874945c132SAlfred Perlstein if (ret != 0) { 7888ebcf97eSGuy Helmer syslog(LOG_ERR, "%lu %s", SM_PROG, clnt_sperrno(ret)); 7898ebcf97eSGuy Helmer exit(1); 7904945c132SAlfred Perlstein } 7914945c132SAlfred Perlstein 7924945c132SAlfred Perlstein nsm_state = stat.state; 7934945c132SAlfred Perlstein 7944945c132SAlfred Perlstein /* setup constant data for SM_MON calls */ 795e4b0fedeSAlfred Perlstein mon_host.mon_id.my_id.my_name = localhost; 7964945c132SAlfred Perlstein mon_host.mon_id.my_id.my_prog = NLM_PROG; 7974945c132SAlfred Perlstein mon_host.mon_id.my_id.my_vers = NLM_SM; 7984945c132SAlfred Perlstein mon_host.mon_id.my_id.my_proc = NLM_SM_NOTIFY; /* bsdi addition */ 7994945c132SAlfred Perlstein } 800e56fbc5aSMatteo Riondato 801e56fbc5aSMatteo Riondato /* 802e56fbc5aSMatteo Riondato * Out of memory, fatal 803e56fbc5aSMatteo Riondato */ 804e56fbc5aSMatteo Riondato void out_of_mem() 805e56fbc5aSMatteo Riondato { 806e56fbc5aSMatteo Riondato syslog(LOG_ERR, "out of memory"); 807e56fbc5aSMatteo Riondato exit(2); 808e56fbc5aSMatteo Riondato } 809