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 49fa9d9930SDoug Rabson #include <sys/param.h> 50fa9d9930SDoug Rabson #include <sys/linker.h> 51fa9d9930SDoug Rabson #include <sys/module.h> 524945c132SAlfred Perlstein #include <sys/socket.h> 53dfdcada3SDoug Rabson #include <sys/stat.h> 544945c132SAlfred Perlstein 55e56fbc5aSMatteo Riondato #include <netinet/in.h> 56e56fbc5aSMatteo Riondato #include <arpa/inet.h> 57e56fbc5aSMatteo Riondato 584945c132SAlfred Perlstein #include <err.h> 594945c132SAlfred Perlstein #include <stdio.h> 604945c132SAlfred Perlstein #include <stdlib.h> 614945c132SAlfred Perlstein #include <errno.h> 624945c132SAlfred Perlstein #include <syslog.h> 634945c132SAlfred Perlstein #include <signal.h> 644945c132SAlfred Perlstein #include <string.h> 654945c132SAlfred Perlstein #include <unistd.h> 664945c132SAlfred Perlstein #include <libutil.h> 674945c132SAlfred Perlstein #include <netconfig.h> 68e56fbc5aSMatteo Riondato #include <netdb.h> 694945c132SAlfred Perlstein 704945c132SAlfred Perlstein #include <rpc/rpc.h> 71bcb53b16SMartin Blapp #include <rpc/rpc_com.h> 724945c132SAlfred Perlstein #include <rpcsvc/sm_inter.h> 734945c132SAlfred Perlstein 744945c132SAlfred Perlstein #include "lockd.h" 754945c132SAlfred Perlstein #include <rpcsvc/nlm_prot.h> 764945c132SAlfred Perlstein 774945c132SAlfred Perlstein int debug_level = 0; /* 0 = no debugging syslog() calls */ 784945c132SAlfred Perlstein int _rpcsvcdirty = 0; 794945c132SAlfred Perlstein 804945c132SAlfred Perlstein int grace_expired; 814945c132SAlfred Perlstein int nsm_state; 82dfdcada3SDoug Rabson int kernel_lockd; 834945c132SAlfred Perlstein pid_t client_pid; 844945c132SAlfred Perlstein struct mon mon_host; 85e56fbc5aSMatteo Riondato char **hosts, *svcport_str = NULL; 86e56fbc5aSMatteo Riondato int nhosts = 0; 87e56fbc5aSMatteo Riondato int xcreated = 0; 88dfdcada3SDoug Rabson char **addrs; /* actually (netid, uaddr) pairs */ 89dfdcada3SDoug Rabson int naddrs; /* count of how many (netid, uaddr) pairs */ 904945c132SAlfred Perlstein 91e56fbc5aSMatteo Riondato void create_service(struct netconfig *nconf); 92dfdcada3SDoug Rabson void lookup_addresses(struct netconfig *nconf); 934945c132SAlfred Perlstein void init_nsm(void); 9433314abeSAlfred Perlstein void nlm_prog_0(struct svc_req *, SVCXPRT *); 9533314abeSAlfred Perlstein void nlm_prog_1(struct svc_req *, SVCXPRT *); 9633314abeSAlfred Perlstein void nlm_prog_3(struct svc_req *, SVCXPRT *); 9733314abeSAlfred Perlstein void nlm_prog_4(struct svc_req *, SVCXPRT *); 98e56fbc5aSMatteo Riondato void out_of_mem(void); 9933314abeSAlfred Perlstein void usage(void); 1004945c132SAlfred Perlstein 10133314abeSAlfred Perlstein void sigalarm_handler(void); 1024945c132SAlfred Perlstein 103dfdcada3SDoug Rabson /* 104dfdcada3SDoug Rabson * XXX move to some header file. 105dfdcada3SDoug Rabson */ 106dfdcada3SDoug Rabson #define _PATH_RPCLOCKDSOCK "/var/run/rpclockd.sock" 107dfdcada3SDoug Rabson 1084945c132SAlfred Perlstein int 109e56fbc5aSMatteo Riondato main(int argc, char **argv) 1104945c132SAlfred Perlstein { 111e56fbc5aSMatteo Riondato int ch, i, s; 112e56fbc5aSMatteo Riondato void *nc_handle; 113e56fbc5aSMatteo Riondato char *endptr, **hosts_bak; 1144945c132SAlfred Perlstein struct sigaction sigalarm; 1154945c132SAlfred Perlstein int grace_period = 30; 1164945c132SAlfred Perlstein struct netconfig *nconf; 117e56fbc5aSMatteo Riondato int have_v6 = 1; 118bcb53b16SMartin Blapp int maxrec = RPC_MAXDATASIZE; 11969f129c9SMatteo Riondato in_port_t svcport = 0; 1204945c132SAlfred Perlstein 121fa9d9930SDoug Rabson while ((ch = getopt(argc, argv, "d:g:h:p:")) != (-1)) { 1224945c132SAlfred Perlstein switch (ch) { 1234945c132SAlfred Perlstein case 'd': 1244945c132SAlfred Perlstein debug_level = atoi(optarg); 1254945c132SAlfred Perlstein if (!debug_level) { 1264945c132SAlfred Perlstein usage(); 1274945c132SAlfred Perlstein /* NOTREACHED */ 1284945c132SAlfred Perlstein } 1294945c132SAlfred Perlstein break; 1304945c132SAlfred Perlstein case 'g': 1314945c132SAlfred Perlstein grace_period = atoi(optarg); 1324945c132SAlfred Perlstein if (!grace_period) { 1334945c132SAlfred Perlstein usage(); 1344945c132SAlfred Perlstein /* NOTREACHED */ 1354945c132SAlfred Perlstein } 1364945c132SAlfred Perlstein break; 137e56fbc5aSMatteo Riondato case 'h': 138e56fbc5aSMatteo Riondato ++nhosts; 139e56fbc5aSMatteo Riondato hosts_bak = hosts; 140e56fbc5aSMatteo Riondato hosts_bak = realloc(hosts, nhosts * sizeof(char *)); 141e56fbc5aSMatteo Riondato if (hosts_bak == NULL) { 142e56fbc5aSMatteo Riondato if (hosts != NULL) { 143e56fbc5aSMatteo Riondato for (i = 0; i < nhosts; i++) 144e56fbc5aSMatteo Riondato free(hosts[i]); 145e56fbc5aSMatteo Riondato free(hosts); 146e56fbc5aSMatteo Riondato out_of_mem(); 147e56fbc5aSMatteo Riondato } 148e56fbc5aSMatteo Riondato } 149e56fbc5aSMatteo Riondato hosts = hosts_bak; 150e56fbc5aSMatteo Riondato hosts[nhosts - 1] = strdup(optarg); 151e56fbc5aSMatteo Riondato if (hosts[nhosts - 1] == NULL) { 152e56fbc5aSMatteo Riondato for (i = 0; i < (nhosts - 1); i++) 153e56fbc5aSMatteo Riondato free(hosts[i]); 154e56fbc5aSMatteo Riondato free(hosts); 155e56fbc5aSMatteo Riondato out_of_mem(); 156e56fbc5aSMatteo Riondato } 157e56fbc5aSMatteo Riondato break; 15869f129c9SMatteo Riondato case 'p': 15969f129c9SMatteo Riondato endptr = NULL; 16069f129c9SMatteo Riondato svcport = (in_port_t)strtoul(optarg, &endptr, 10); 16169f129c9SMatteo Riondato if (endptr == NULL || *endptr != '\0' || 16269f129c9SMatteo Riondato svcport == 0 || svcport >= IPPORT_MAX) 16369f129c9SMatteo Riondato usage(); 164e56fbc5aSMatteo Riondato svcport_str = strdup(optarg); 16569f129c9SMatteo Riondato break; 1664945c132SAlfred Perlstein default: 1674945c132SAlfred Perlstein case '?': 1684945c132SAlfred Perlstein usage(); 1694945c132SAlfred Perlstein /* NOTREACHED */ 1704945c132SAlfred Perlstein } 1714945c132SAlfred Perlstein } 1724945c132SAlfred Perlstein if (geteuid()) { /* This command allowed only to root */ 1734945c132SAlfred Perlstein fprintf(stderr, "Sorry. You are not superuser\n"); 1744945c132SAlfred Perlstein exit(1); 1754945c132SAlfred Perlstein } 1764945c132SAlfred Perlstein 177fa9d9930SDoug Rabson kernel_lockd = FALSE; 178fa9d9930SDoug Rabson if (modfind("nfslockd") < 0) { 179fa9d9930SDoug Rabson if (kldload("nfslockd") < 0) { 180fa9d9930SDoug Rabson fprintf(stderr, "Can't find or load kernel support for rpc.lockd - using non-kernel implementation\n"); 181fa9d9930SDoug Rabson } 182fa9d9930SDoug Rabson kernel_lockd = TRUE; 183fa9d9930SDoug Rabson } else { 184fa9d9930SDoug Rabson kernel_lockd = TRUE; 185fa9d9930SDoug Rabson } 186fa9d9930SDoug Rabson 1874945c132SAlfred Perlstein (void)rpcb_unset(NLM_PROG, NLM_SM, NULL); 1884945c132SAlfred Perlstein (void)rpcb_unset(NLM_PROG, NLM_VERS, NULL); 1894945c132SAlfred Perlstein (void)rpcb_unset(NLM_PROG, NLM_VERSX, NULL); 1904945c132SAlfred Perlstein (void)rpcb_unset(NLM_PROG, NLM_VERS4, NULL); 1914945c132SAlfred Perlstein 1924945c132SAlfred Perlstein /* 1934945c132SAlfred Perlstein * Check if IPv6 support is present. 1944945c132SAlfred Perlstein */ 1954945c132SAlfred Perlstein s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); 1964945c132SAlfred Perlstein if (s < 0) 197e56fbc5aSMatteo Riondato have_v6 = 0; 198e56fbc5aSMatteo Riondato else 1994945c132SAlfred Perlstein close(s); 20069f129c9SMatteo Riondato 201bcb53b16SMartin Blapp rpc_control(RPC_SVC_CONNMAXREC_SET, &maxrec); 202bcb53b16SMartin Blapp 203e56fbc5aSMatteo Riondato /* 204e56fbc5aSMatteo Riondato * If no hosts were specified, add a wildcard entry to bind to 205e56fbc5aSMatteo Riondato * INADDR_ANY. Otherwise make sure 127.0.0.1 and ::1 are added to the 206e56fbc5aSMatteo Riondato * list. 207e56fbc5aSMatteo Riondato */ 208e56fbc5aSMatteo Riondato if (nhosts == 0) { 209e56fbc5aSMatteo Riondato hosts = malloc(sizeof(char**)); 210e56fbc5aSMatteo Riondato if (hosts == NULL) 211e56fbc5aSMatteo Riondato out_of_mem(); 2124945c132SAlfred Perlstein 213e56fbc5aSMatteo Riondato hosts[0] = "*"; 214e56fbc5aSMatteo Riondato nhosts = 1; 21569f129c9SMatteo Riondato } else { 216e56fbc5aSMatteo Riondato hosts_bak = hosts; 217e56fbc5aSMatteo Riondato if (have_v6) { 218e56fbc5aSMatteo Riondato hosts_bak = realloc(hosts, (nhosts + 2) * 219e56fbc5aSMatteo Riondato sizeof(char *)); 220e56fbc5aSMatteo Riondato if (hosts_bak == NULL) { 221e56fbc5aSMatteo Riondato for (i = 0; i < nhosts; i++) 222e56fbc5aSMatteo Riondato free(hosts[i]); 223e56fbc5aSMatteo Riondato free(hosts); 224e56fbc5aSMatteo Riondato out_of_mem(); 225e56fbc5aSMatteo Riondato } else 226e56fbc5aSMatteo Riondato hosts = hosts_bak; 227e56fbc5aSMatteo Riondato 228e56fbc5aSMatteo Riondato nhosts += 2; 229e56fbc5aSMatteo Riondato hosts[nhosts - 2] = "::1"; 230e56fbc5aSMatteo Riondato } else { 231e56fbc5aSMatteo Riondato hosts_bak = realloc(hosts, (nhosts + 1) * sizeof(char *)); 232e56fbc5aSMatteo Riondato if (hosts_bak == NULL) { 233e56fbc5aSMatteo Riondato for (i = 0; i < nhosts; i++) 234e56fbc5aSMatteo Riondato free(hosts[i]); 235e56fbc5aSMatteo Riondato 236e56fbc5aSMatteo Riondato free(hosts); 237e56fbc5aSMatteo Riondato out_of_mem(); 238e56fbc5aSMatteo Riondato } else { 239e56fbc5aSMatteo Riondato nhosts += 1; 240e56fbc5aSMatteo Riondato hosts = hosts_bak; 241e56fbc5aSMatteo Riondato } 242e56fbc5aSMatteo Riondato } 243e56fbc5aSMatteo Riondato hosts[nhosts - 1] = "127.0.0.1"; 24469f129c9SMatteo Riondato } 24569f129c9SMatteo Riondato 246dfdcada3SDoug Rabson if (kernel_lockd) { 247dfdcada3SDoug Rabson /* 248dfdcada3SDoug Rabson * For the kernel lockd case, we run a cut-down RPC 249dfdcada3SDoug Rabson * service on a local-domain socket. The kernel's RPC 250dfdcada3SDoug Rabson * server will pass what it can't handle (mainly 251dfdcada3SDoug Rabson * client replies) down to us. This can go away 252dfdcada3SDoug Rabson * entirely if/when we move the client side of NFS 253dfdcada3SDoug Rabson * locking into the kernel. 254dfdcada3SDoug Rabson */ 255dfdcada3SDoug Rabson struct sockaddr_un sun; 256dfdcada3SDoug Rabson int fd, oldmask; 257dfdcada3SDoug Rabson SVCXPRT *xprt; 258dfdcada3SDoug Rabson 259dfdcada3SDoug Rabson memset(&sun, 0, sizeof sun); 260dfdcada3SDoug Rabson sun.sun_family = AF_LOCAL; 261dfdcada3SDoug Rabson unlink(_PATH_RPCLOCKDSOCK); 262dfdcada3SDoug Rabson strcpy(sun.sun_path, _PATH_RPCLOCKDSOCK); 263dfdcada3SDoug Rabson sun.sun_len = SUN_LEN(&sun); 264dfdcada3SDoug Rabson fd = socket(AF_LOCAL, SOCK_STREAM, 0); 265dfdcada3SDoug Rabson if (!fd) { 266dfdcada3SDoug Rabson err(1, "Can't create local lockd socket"); 267dfdcada3SDoug Rabson } 268dfdcada3SDoug Rabson oldmask = umask(S_IXUSR|S_IRWXG|S_IRWXO); 269dfdcada3SDoug Rabson if (bind(fd, (struct sockaddr *) &sun, sun.sun_len) < 0) { 270dfdcada3SDoug Rabson err(1, "Can't bind local lockd socket"); 271dfdcada3SDoug Rabson } 272dfdcada3SDoug Rabson umask(oldmask); 273dfdcada3SDoug Rabson if (listen(fd, SOMAXCONN) < 0) { 274dfdcada3SDoug Rabson err(1, "Can't listen on local lockd socket"); 275dfdcada3SDoug Rabson } 276dfdcada3SDoug Rabson xprt = svc_vc_create(fd, RPC_MAXDATASIZE, RPC_MAXDATASIZE); 277dfdcada3SDoug Rabson if (!xprt) { 278dfdcada3SDoug Rabson err(1, "Can't create transport for local lockd socket"); 279dfdcada3SDoug Rabson } 280dfdcada3SDoug Rabson if (!svc_reg(xprt, NLM_PROG, NLM_VERS4, nlm_prog_4, NULL)) { 281dfdcada3SDoug Rabson err(1, "Can't register service for local lockd socket"); 282dfdcada3SDoug Rabson } 283dfdcada3SDoug Rabson 284dfdcada3SDoug Rabson /* 285dfdcada3SDoug Rabson * We need to look up the addresses so that we can 286dfdcada3SDoug Rabson * hand uaddrs (ascii encoded address+port strings) to 287dfdcada3SDoug Rabson * the kernel. 288dfdcada3SDoug Rabson */ 289dfdcada3SDoug Rabson nc_handle = setnetconfig(); 290dfdcada3SDoug Rabson while ((nconf = getnetconfig(nc_handle))) { 291dfdcada3SDoug Rabson /* We want to listen only on udp6, tcp6, udp, tcp transports */ 292dfdcada3SDoug Rabson if (nconf->nc_flag & NC_VISIBLE) { 293dfdcada3SDoug Rabson /* Skip if there's no IPv6 support */ 294dfdcada3SDoug Rabson if (have_v6 == 0 && strcmp(nconf->nc_protofmly, "inet6") == 0) { 295dfdcada3SDoug Rabson /* DO NOTHING */ 296dfdcada3SDoug Rabson } else { 297dfdcada3SDoug Rabson lookup_addresses(nconf); 298dfdcada3SDoug Rabson } 299dfdcada3SDoug Rabson } 300dfdcada3SDoug Rabson } 301dfdcada3SDoug Rabson endnetconfig(nc_handle); 302dfdcada3SDoug Rabson } else { 303e56fbc5aSMatteo Riondato nc_handle = setnetconfig(); 304e56fbc5aSMatteo Riondato while ((nconf = getnetconfig(nc_handle))) { 305e56fbc5aSMatteo Riondato /* We want to listen only on udp6, tcp6, udp, tcp transports */ 306e56fbc5aSMatteo Riondato if (nconf->nc_flag & NC_VISIBLE) { 307e56fbc5aSMatteo Riondato /* Skip if there's no IPv6 support */ 308e56fbc5aSMatteo Riondato if (have_v6 == 0 && strcmp(nconf->nc_protofmly, "inet6") == 0) { 309e56fbc5aSMatteo Riondato /* DO NOTHING */ 310e56fbc5aSMatteo Riondato } else { 311e56fbc5aSMatteo Riondato create_service(nconf); 3124945c132SAlfred Perlstein } 3134945c132SAlfred Perlstein } 3144945c132SAlfred Perlstein } 315e56fbc5aSMatteo Riondato endnetconfig(nc_handle); 316dfdcada3SDoug Rabson } 3174945c132SAlfred Perlstein 3184945c132SAlfred Perlstein /* 3194945c132SAlfred Perlstein * Note that it is NOT sensible to run this program from inetd - the 3204945c132SAlfred Perlstein * protocol assumes that it will run immediately at boot time. 3214945c132SAlfred Perlstein */ 3223d81d1adSMichael Reifenberger if (daemon(0, debug_level > 0)) { 3234945c132SAlfred Perlstein err(1, "cannot fork"); 3244945c132SAlfred Perlstein /* NOTREACHED */ 3254945c132SAlfred Perlstein } 3264945c132SAlfred Perlstein 3274945c132SAlfred Perlstein openlog("rpc.lockd", 0, LOG_DAEMON); 3284945c132SAlfred Perlstein if (debug_level) 3294945c132SAlfred Perlstein syslog(LOG_INFO, "Starting, debug level %d", debug_level); 3304945c132SAlfred Perlstein else 3314945c132SAlfred Perlstein syslog(LOG_INFO, "Starting"); 3324945c132SAlfred Perlstein 3334945c132SAlfred Perlstein sigalarm.sa_handler = (sig_t) sigalarm_handler; 3344945c132SAlfred Perlstein sigemptyset(&sigalarm.sa_mask); 3354945c132SAlfred Perlstein sigalarm.sa_flags = SA_RESETHAND; /* should only happen once */ 3364945c132SAlfred Perlstein sigalarm.sa_flags |= SA_RESTART; 3374945c132SAlfred Perlstein if (sigaction(SIGALRM, &sigalarm, NULL) != 0) { 3384945c132SAlfred Perlstein syslog(LOG_WARNING, "sigaction(SIGALRM) failed: %s", 3394945c132SAlfred Perlstein strerror(errno)); 3404945c132SAlfred Perlstein exit(1); 3414945c132SAlfred Perlstein } 342dfdcada3SDoug Rabson 343dfdcada3SDoug Rabson if (kernel_lockd) { 344dfdcada3SDoug Rabson client_pid = client_request(); 345dfdcada3SDoug Rabson 346dfdcada3SDoug Rabson /* 347dfdcada3SDoug Rabson * Create a child process to enter the kernel and then 348dfdcada3SDoug Rabson * wait for RPCs on our local domain socket. 349dfdcada3SDoug Rabson */ 350dfdcada3SDoug Rabson if (!fork()) 351dfdcada3SDoug Rabson nlm_syscall(debug_level, grace_period, naddrs, addrs); 352dfdcada3SDoug Rabson else 353dfdcada3SDoug Rabson svc_run(); 354dfdcada3SDoug Rabson } else { 3554945c132SAlfred Perlstein grace_expired = 0; 35635a64c9fSThomas Quinot alarm(grace_period); 3574945c132SAlfred Perlstein 3584945c132SAlfred Perlstein init_nsm(); 3594945c132SAlfred Perlstein 3604945c132SAlfred Perlstein client_pid = client_request(); 3614945c132SAlfred Perlstein 3624945c132SAlfred Perlstein svc_run(); /* Should never return */ 363dfdcada3SDoug Rabson } 3644945c132SAlfred Perlstein exit(1); 3654945c132SAlfred Perlstein } 3664945c132SAlfred Perlstein 367e56fbc5aSMatteo Riondato /* 368e56fbc5aSMatteo Riondato * This routine creates and binds sockets on the appropriate 369e56fbc5aSMatteo Riondato * addresses. It gets called one time for each transport and 370e56fbc5aSMatteo Riondato * registrates the service with rpcbind on that trasport. 371e56fbc5aSMatteo Riondato */ 372e56fbc5aSMatteo Riondato void 373e56fbc5aSMatteo Riondato create_service(struct netconfig *nconf) 374e56fbc5aSMatteo Riondato { 375e56fbc5aSMatteo Riondato struct addrinfo hints, *res = NULL; 376e56fbc5aSMatteo Riondato struct sockaddr_in *sin; 377e56fbc5aSMatteo Riondato struct sockaddr_in6 *sin6; 378e56fbc5aSMatteo Riondato struct __rpc_sockinfo si; 379e56fbc5aSMatteo Riondato struct netbuf servaddr; 380e56fbc5aSMatteo Riondato SVCXPRT *transp = NULL; 381e56fbc5aSMatteo Riondato int aicode; 382e56fbc5aSMatteo Riondato int fd; 383e56fbc5aSMatteo Riondato int nhostsbak; 384e56fbc5aSMatteo Riondato int r; 385e56fbc5aSMatteo Riondato int registered = 0; 386e56fbc5aSMatteo Riondato u_int32_t host_addr[4]; /* IPv4 or IPv6 */ 387e56fbc5aSMatteo Riondato 388e56fbc5aSMatteo Riondato if ((nconf->nc_semantics != NC_TPI_CLTS) && 389e56fbc5aSMatteo Riondato (nconf->nc_semantics != NC_TPI_COTS) && 390e56fbc5aSMatteo Riondato (nconf->nc_semantics != NC_TPI_COTS_ORD)) 391e56fbc5aSMatteo Riondato return; /* not my type */ 392e56fbc5aSMatteo Riondato 393e56fbc5aSMatteo Riondato /* 394e56fbc5aSMatteo Riondato * XXX - using RPC library internal functions. 395e56fbc5aSMatteo Riondato */ 396e56fbc5aSMatteo Riondato if (!__rpc_nconf2sockinfo(nconf, &si)) { 397e56fbc5aSMatteo Riondato syslog(LOG_ERR, "cannot get information for %s", 398e56fbc5aSMatteo Riondato nconf->nc_netid); 399e56fbc5aSMatteo Riondato return; 400e56fbc5aSMatteo Riondato } 401e56fbc5aSMatteo Riondato 402e56fbc5aSMatteo Riondato /* Get rpc.statd's address on this transport */ 403e56fbc5aSMatteo Riondato memset(&hints, 0, sizeof hints); 404e56fbc5aSMatteo Riondato hints.ai_flags = AI_PASSIVE; 405e56fbc5aSMatteo Riondato hints.ai_family = si.si_af; 406e56fbc5aSMatteo Riondato hints.ai_socktype = si.si_socktype; 407e56fbc5aSMatteo Riondato hints.ai_protocol = si.si_proto; 408e56fbc5aSMatteo Riondato 409e56fbc5aSMatteo Riondato /* 410e56fbc5aSMatteo Riondato * Bind to specific IPs if asked to 411e56fbc5aSMatteo Riondato */ 412e56fbc5aSMatteo Riondato nhostsbak = nhosts; 413e56fbc5aSMatteo Riondato while (nhostsbak > 0) { 414e56fbc5aSMatteo Riondato --nhostsbak; 415e56fbc5aSMatteo Riondato 416e56fbc5aSMatteo Riondato /* 417e56fbc5aSMatteo Riondato * XXX - using RPC library internal functions. 418e56fbc5aSMatteo Riondato */ 419e56fbc5aSMatteo Riondato if ((fd = __rpc_nconf2fd(nconf)) < 0) { 420e56fbc5aSMatteo Riondato syslog(LOG_ERR, "cannot create socket for %s", 421e56fbc5aSMatteo Riondato nconf->nc_netid); 422e56fbc5aSMatteo Riondato continue; 423e56fbc5aSMatteo Riondato } 424e56fbc5aSMatteo Riondato 425e56fbc5aSMatteo Riondato switch (hints.ai_family) { 426e56fbc5aSMatteo Riondato case AF_INET: 427e56fbc5aSMatteo Riondato if (inet_pton(AF_INET, hosts[nhostsbak], 428e56fbc5aSMatteo Riondato host_addr) == 1) { 429e56fbc5aSMatteo Riondato hints.ai_flags &= AI_NUMERICHOST; 430e56fbc5aSMatteo Riondato } else { 431e56fbc5aSMatteo Riondato /* 432e56fbc5aSMatteo Riondato * Skip if we have an AF_INET6 address. 433e56fbc5aSMatteo Riondato */ 434e56fbc5aSMatteo Riondato if (inet_pton(AF_INET6, hosts[nhostsbak], 435e56fbc5aSMatteo Riondato host_addr) == 1) { 436e56fbc5aSMatteo Riondato close(fd); 437e56fbc5aSMatteo Riondato continue; 438e56fbc5aSMatteo Riondato } 439e56fbc5aSMatteo Riondato } 440e56fbc5aSMatteo Riondato break; 441e56fbc5aSMatteo Riondato case AF_INET6: 442e56fbc5aSMatteo Riondato if (inet_pton(AF_INET6, hosts[nhostsbak], 443e56fbc5aSMatteo Riondato host_addr) == 1) { 444e56fbc5aSMatteo Riondato hints.ai_flags &= AI_NUMERICHOST; 445e56fbc5aSMatteo Riondato } else { 446e56fbc5aSMatteo Riondato /* 447e56fbc5aSMatteo Riondato * Skip if we have an AF_INET address. 448e56fbc5aSMatteo Riondato */ 449e56fbc5aSMatteo Riondato if (inet_pton(AF_INET, hosts[nhostsbak], 450e56fbc5aSMatteo Riondato host_addr) == 1) { 451e56fbc5aSMatteo Riondato close(fd); 452e56fbc5aSMatteo Riondato continue; 453e56fbc5aSMatteo Riondato } 454e56fbc5aSMatteo Riondato } 455e56fbc5aSMatteo Riondato break; 456e56fbc5aSMatteo Riondato default: 457e56fbc5aSMatteo Riondato break; 458e56fbc5aSMatteo Riondato } 459e56fbc5aSMatteo Riondato 460e56fbc5aSMatteo Riondato /* 461e56fbc5aSMatteo Riondato * If no hosts were specified, just bind to INADDR_ANY 462e56fbc5aSMatteo Riondato */ 463e56fbc5aSMatteo Riondato if (strcmp("*", hosts[nhostsbak]) == 0) { 464e56fbc5aSMatteo Riondato if (svcport_str == NULL) { 465e56fbc5aSMatteo Riondato res = malloc(sizeof(struct addrinfo)); 466e56fbc5aSMatteo Riondato if (res == NULL) 467e56fbc5aSMatteo Riondato out_of_mem(); 468e56fbc5aSMatteo Riondato res->ai_flags = hints.ai_flags; 469e56fbc5aSMatteo Riondato res->ai_family = hints.ai_family; 470e56fbc5aSMatteo Riondato res->ai_protocol = hints.ai_protocol; 471e56fbc5aSMatteo Riondato switch (res->ai_family) { 472e56fbc5aSMatteo Riondato case AF_INET: 473e56fbc5aSMatteo Riondato sin = malloc(sizeof(struct sockaddr_in)); 474e56fbc5aSMatteo Riondato if (sin == NULL) 475e56fbc5aSMatteo Riondato out_of_mem(); 476e56fbc5aSMatteo Riondato sin->sin_family = AF_INET; 477e56fbc5aSMatteo Riondato sin->sin_port = htons(0); 478e56fbc5aSMatteo Riondato sin->sin_addr.s_addr = htonl(INADDR_ANY); 479e56fbc5aSMatteo Riondato res->ai_addr = (struct sockaddr*) sin; 480e56fbc5aSMatteo Riondato res->ai_addrlen = (socklen_t) 481e56fbc5aSMatteo Riondato sizeof(res->ai_addr); 482e56fbc5aSMatteo Riondato break; 483e56fbc5aSMatteo Riondato case AF_INET6: 484e56fbc5aSMatteo Riondato sin6 = malloc(sizeof(struct sockaddr_in6)); 48596e460ecSMatteo Riondato if (sin6 == NULL) 486e56fbc5aSMatteo Riondato out_of_mem(); 487e56fbc5aSMatteo Riondato sin6->sin6_family = AF_INET6; 488e56fbc5aSMatteo Riondato sin6->sin6_port = htons(0); 489e56fbc5aSMatteo Riondato sin6->sin6_addr = in6addr_any; 490e56fbc5aSMatteo Riondato res->ai_addr = (struct sockaddr*) sin6; 491e56fbc5aSMatteo Riondato res->ai_addrlen = (socklen_t) sizeof(res->ai_addr); 492e56fbc5aSMatteo Riondato break; 493e56fbc5aSMatteo Riondato default: 494e56fbc5aSMatteo Riondato break; 495e56fbc5aSMatteo Riondato } 496e56fbc5aSMatteo Riondato } else { 497e56fbc5aSMatteo Riondato if ((aicode = getaddrinfo(NULL, svcport_str, 498e56fbc5aSMatteo Riondato &hints, &res)) != 0) { 499e56fbc5aSMatteo Riondato syslog(LOG_ERR, 500e56fbc5aSMatteo Riondato "cannot get local address for %s: %s", 501e56fbc5aSMatteo Riondato nconf->nc_netid, 502e56fbc5aSMatteo Riondato gai_strerror(aicode)); 503e56fbc5aSMatteo Riondato continue; 504e56fbc5aSMatteo Riondato } 505e56fbc5aSMatteo Riondato } 506e56fbc5aSMatteo Riondato } else { 507e56fbc5aSMatteo Riondato if ((aicode = getaddrinfo(hosts[nhostsbak], svcport_str, 508e56fbc5aSMatteo Riondato &hints, &res)) != 0) { 509e56fbc5aSMatteo Riondato syslog(LOG_ERR, 510e56fbc5aSMatteo Riondato "cannot get local address for %s: %s", 511e56fbc5aSMatteo Riondato nconf->nc_netid, gai_strerror(aicode)); 512e56fbc5aSMatteo Riondato continue; 513e56fbc5aSMatteo Riondato } 514e56fbc5aSMatteo Riondato } 515e56fbc5aSMatteo Riondato 516e56fbc5aSMatteo Riondato r = bindresvport_sa(fd, res->ai_addr); 517e56fbc5aSMatteo Riondato if (r != 0) { 518e56fbc5aSMatteo Riondato syslog(LOG_ERR, "bindresvport_sa: %m"); 519e56fbc5aSMatteo Riondato exit(1); 520e56fbc5aSMatteo Riondato } 521e56fbc5aSMatteo Riondato 522e56fbc5aSMatteo Riondato transp = svc_tli_create(fd, nconf, NULL, 523e56fbc5aSMatteo Riondato RPC_MAXDATASIZE, RPC_MAXDATASIZE); 524e56fbc5aSMatteo Riondato 525e56fbc5aSMatteo Riondato if (transp != (SVCXPRT *) NULL) { 526e56fbc5aSMatteo Riondato if (!svc_reg(transp, NLM_PROG, NLM_SM, nlm_prog_0, 527e56fbc5aSMatteo Riondato NULL)) 528e56fbc5aSMatteo Riondato syslog(LOG_ERR, 529e56fbc5aSMatteo Riondato "can't register %s NLM_PROG, NLM_SM service", 530e56fbc5aSMatteo Riondato nconf->nc_netid); 531e56fbc5aSMatteo Riondato 532e56fbc5aSMatteo Riondato if (!svc_reg(transp, NLM_PROG, NLM_VERS, nlm_prog_1, 533e56fbc5aSMatteo Riondato NULL)) 534e56fbc5aSMatteo Riondato syslog(LOG_ERR, 535e56fbc5aSMatteo Riondato "can't register %s NLM_PROG, NLM_VERS service", 536e56fbc5aSMatteo Riondato nconf->nc_netid); 537e56fbc5aSMatteo Riondato 538e56fbc5aSMatteo Riondato if (!svc_reg(transp, NLM_PROG, NLM_VERSX, nlm_prog_3, 539e56fbc5aSMatteo Riondato NULL)) 540e56fbc5aSMatteo Riondato syslog(LOG_ERR, 541e56fbc5aSMatteo Riondato "can't register %s NLM_PROG, NLM_VERSX service", 542e56fbc5aSMatteo Riondato nconf->nc_netid); 543e56fbc5aSMatteo Riondato 544e56fbc5aSMatteo Riondato if (!svc_reg(transp, NLM_PROG, NLM_VERS4, nlm_prog_4, 545e56fbc5aSMatteo Riondato NULL)) 546e56fbc5aSMatteo Riondato syslog(LOG_ERR, 547e56fbc5aSMatteo Riondato "can't register %s NLM_PROG, NLM_VERS4 service", 548e56fbc5aSMatteo Riondato nconf->nc_netid); 549e56fbc5aSMatteo Riondato 550e56fbc5aSMatteo Riondato } else 551e56fbc5aSMatteo Riondato syslog(LOG_WARNING, "can't create %s services", 552e56fbc5aSMatteo Riondato nconf->nc_netid); 553e56fbc5aSMatteo Riondato 554e56fbc5aSMatteo Riondato if (registered == 0) { 555e56fbc5aSMatteo Riondato registered = 1; 556e56fbc5aSMatteo Riondato memset(&hints, 0, sizeof hints); 557e56fbc5aSMatteo Riondato hints.ai_flags = AI_PASSIVE; 558e56fbc5aSMatteo Riondato hints.ai_family = si.si_af; 559e56fbc5aSMatteo Riondato hints.ai_socktype = si.si_socktype; 560e56fbc5aSMatteo Riondato hints.ai_protocol = si.si_proto; 561e56fbc5aSMatteo Riondato 562e56fbc5aSMatteo Riondato if (svcport_str == NULL) { 563e56fbc5aSMatteo Riondato svcport_str = malloc(NI_MAXSERV * sizeof(char)); 564e56fbc5aSMatteo Riondato if (svcport_str == NULL) 565e56fbc5aSMatteo Riondato out_of_mem(); 566e56fbc5aSMatteo Riondato 567e56fbc5aSMatteo Riondato if (getnameinfo(res->ai_addr, 568e56fbc5aSMatteo Riondato res->ai_addr->sa_len, NULL, NI_MAXHOST, 569e56fbc5aSMatteo Riondato svcport_str, NI_MAXSERV * sizeof(char), 570e56fbc5aSMatteo Riondato NI_NUMERICHOST | NI_NUMERICSERV)) 571e56fbc5aSMatteo Riondato errx(1, "Cannot get port number"); 572e56fbc5aSMatteo Riondato } 573e56fbc5aSMatteo Riondato 574e56fbc5aSMatteo Riondato if((aicode = getaddrinfo(NULL, svcport_str, &hints, 575e56fbc5aSMatteo Riondato &res)) != 0) { 576e56fbc5aSMatteo Riondato syslog(LOG_ERR, "cannot get local address: %s", 577e56fbc5aSMatteo Riondato gai_strerror(aicode)); 578e56fbc5aSMatteo Riondato exit(1); 579e56fbc5aSMatteo Riondato } 580e56fbc5aSMatteo Riondato 581e56fbc5aSMatteo Riondato servaddr.buf = malloc(res->ai_addrlen); 582e56fbc5aSMatteo Riondato memcpy(servaddr.buf, res->ai_addr, res->ai_addrlen); 583e56fbc5aSMatteo Riondato servaddr.len = res->ai_addrlen; 584e56fbc5aSMatteo Riondato 585e56fbc5aSMatteo Riondato rpcb_set(NLM_PROG, NLM_SM, nconf, &servaddr); 586e56fbc5aSMatteo Riondato rpcb_set(NLM_PROG, NLM_VERS, nconf, &servaddr); 587e56fbc5aSMatteo Riondato rpcb_set(NLM_PROG, NLM_VERSX, nconf, &servaddr); 588e56fbc5aSMatteo Riondato rpcb_set(NLM_PROG, NLM_VERS4, nconf, &servaddr); 589e56fbc5aSMatteo Riondato 590e56fbc5aSMatteo Riondato xcreated++; 591e56fbc5aSMatteo Riondato freeaddrinfo(res); 592e56fbc5aSMatteo Riondato } 593e56fbc5aSMatteo Riondato } /* end while */ 594e56fbc5aSMatteo Riondato } 595e56fbc5aSMatteo Riondato 596dfdcada3SDoug Rabson /* 597dfdcada3SDoug Rabson * Look up addresses for the kernel to create transports for. 598dfdcada3SDoug Rabson */ 599dfdcada3SDoug Rabson void 600dfdcada3SDoug Rabson lookup_addresses(struct netconfig *nconf) 601dfdcada3SDoug Rabson { 602dfdcada3SDoug Rabson struct addrinfo hints, *res = NULL; 603dfdcada3SDoug Rabson struct sockaddr_in *sin; 604dfdcada3SDoug Rabson struct sockaddr_in6 *sin6; 605dfdcada3SDoug Rabson struct __rpc_sockinfo si; 606dfdcada3SDoug Rabson struct netbuf servaddr; 607dfdcada3SDoug Rabson SVCXPRT *transp = NULL; 608dfdcada3SDoug Rabson int aicode; 609dfdcada3SDoug Rabson int nhostsbak; 610dfdcada3SDoug Rabson int r; 611dfdcada3SDoug Rabson int registered = 0; 612dfdcada3SDoug Rabson u_int32_t host_addr[4]; /* IPv4 or IPv6 */ 613dfdcada3SDoug Rabson char *uaddr; 614dfdcada3SDoug Rabson 615dfdcada3SDoug Rabson if ((nconf->nc_semantics != NC_TPI_CLTS) && 616dfdcada3SDoug Rabson (nconf->nc_semantics != NC_TPI_COTS) && 617dfdcada3SDoug Rabson (nconf->nc_semantics != NC_TPI_COTS_ORD)) 618dfdcada3SDoug Rabson return; /* not my type */ 619dfdcada3SDoug Rabson 620dfdcada3SDoug Rabson /* 621dfdcada3SDoug Rabson * XXX - using RPC library internal functions. 622dfdcada3SDoug Rabson */ 623dfdcada3SDoug Rabson if (!__rpc_nconf2sockinfo(nconf, &si)) { 624dfdcada3SDoug Rabson syslog(LOG_ERR, "cannot get information for %s", 625dfdcada3SDoug Rabson nconf->nc_netid); 626dfdcada3SDoug Rabson return; 627dfdcada3SDoug Rabson } 628dfdcada3SDoug Rabson 629dfdcada3SDoug Rabson /* Get rpc.statd's address on this transport */ 630dfdcada3SDoug Rabson memset(&hints, 0, sizeof hints); 631dfdcada3SDoug Rabson hints.ai_flags = AI_PASSIVE; 632dfdcada3SDoug Rabson hints.ai_family = si.si_af; 633dfdcada3SDoug Rabson hints.ai_socktype = si.si_socktype; 634dfdcada3SDoug Rabson hints.ai_protocol = si.si_proto; 635dfdcada3SDoug Rabson 636dfdcada3SDoug Rabson /* 637dfdcada3SDoug Rabson * Bind to specific IPs if asked to 638dfdcada3SDoug Rabson */ 639dfdcada3SDoug Rabson nhostsbak = nhosts; 640dfdcada3SDoug Rabson while (nhostsbak > 0) { 641dfdcada3SDoug Rabson --nhostsbak; 642dfdcada3SDoug Rabson 643dfdcada3SDoug Rabson switch (hints.ai_family) { 644dfdcada3SDoug Rabson case AF_INET: 645dfdcada3SDoug Rabson if (inet_pton(AF_INET, hosts[nhostsbak], 646dfdcada3SDoug Rabson host_addr) == 1) { 647dfdcada3SDoug Rabson hints.ai_flags &= AI_NUMERICHOST; 648dfdcada3SDoug Rabson } else { 649dfdcada3SDoug Rabson /* 650dfdcada3SDoug Rabson * Skip if we have an AF_INET6 address. 651dfdcada3SDoug Rabson */ 652dfdcada3SDoug Rabson if (inet_pton(AF_INET6, hosts[nhostsbak], 653dfdcada3SDoug Rabson host_addr) == 1) { 654dfdcada3SDoug Rabson continue; 655dfdcada3SDoug Rabson } 656dfdcada3SDoug Rabson } 657dfdcada3SDoug Rabson break; 658dfdcada3SDoug Rabson case AF_INET6: 659dfdcada3SDoug Rabson if (inet_pton(AF_INET6, hosts[nhostsbak], 660dfdcada3SDoug Rabson host_addr) == 1) { 661dfdcada3SDoug Rabson hints.ai_flags &= AI_NUMERICHOST; 662dfdcada3SDoug Rabson } else { 663dfdcada3SDoug Rabson /* 664dfdcada3SDoug Rabson * Skip if we have an AF_INET address. 665dfdcada3SDoug Rabson */ 666dfdcada3SDoug Rabson if (inet_pton(AF_INET, hosts[nhostsbak], 667dfdcada3SDoug Rabson host_addr) == 1) { 668dfdcada3SDoug Rabson continue; 669dfdcada3SDoug Rabson } 670dfdcada3SDoug Rabson } 671dfdcada3SDoug Rabson break; 672dfdcada3SDoug Rabson default: 673dfdcada3SDoug Rabson break; 674dfdcada3SDoug Rabson } 675dfdcada3SDoug Rabson 676dfdcada3SDoug Rabson /* 677dfdcada3SDoug Rabson * If no hosts were specified, just bind to INADDR_ANY 678dfdcada3SDoug Rabson */ 679dfdcada3SDoug Rabson if (strcmp("*", hosts[nhostsbak]) == 0) { 680dfdcada3SDoug Rabson if (svcport_str == NULL) { 681dfdcada3SDoug Rabson res = malloc(sizeof(struct addrinfo)); 682dfdcada3SDoug Rabson if (res == NULL) 683dfdcada3SDoug Rabson out_of_mem(); 684dfdcada3SDoug Rabson res->ai_flags = hints.ai_flags; 685dfdcada3SDoug Rabson res->ai_family = hints.ai_family; 686dfdcada3SDoug Rabson res->ai_protocol = hints.ai_protocol; 687dfdcada3SDoug Rabson switch (res->ai_family) { 688dfdcada3SDoug Rabson case AF_INET: 689dfdcada3SDoug Rabson sin = malloc(sizeof(struct sockaddr_in)); 690dfdcada3SDoug Rabson if (sin == NULL) 691dfdcada3SDoug Rabson out_of_mem(); 692dfdcada3SDoug Rabson sin->sin_family = AF_INET; 693dfdcada3SDoug Rabson sin->sin_port = htons(0); 694dfdcada3SDoug Rabson sin->sin_addr.s_addr = htonl(INADDR_ANY); 695dfdcada3SDoug Rabson res->ai_addr = (struct sockaddr*) sin; 696dfdcada3SDoug Rabson res->ai_addrlen = (socklen_t) 697dfdcada3SDoug Rabson sizeof(res->ai_addr); 698dfdcada3SDoug Rabson break; 699dfdcada3SDoug Rabson case AF_INET6: 700dfdcada3SDoug Rabson sin6 = malloc(sizeof(struct sockaddr_in6)); 701dfdcada3SDoug Rabson if (sin6 == NULL) 702dfdcada3SDoug Rabson out_of_mem(); 703dfdcada3SDoug Rabson sin6->sin6_family = AF_INET6; 704dfdcada3SDoug Rabson sin6->sin6_port = htons(0); 705dfdcada3SDoug Rabson sin6->sin6_addr = in6addr_any; 706dfdcada3SDoug Rabson res->ai_addr = (struct sockaddr*) sin6; 707dfdcada3SDoug Rabson res->ai_addrlen = (socklen_t) sizeof(res->ai_addr); 708dfdcada3SDoug Rabson break; 709dfdcada3SDoug Rabson default: 710dfdcada3SDoug Rabson break; 711dfdcada3SDoug Rabson } 712dfdcada3SDoug Rabson } else { 713dfdcada3SDoug Rabson if ((aicode = getaddrinfo(NULL, svcport_str, 714dfdcada3SDoug Rabson &hints, &res)) != 0) { 715dfdcada3SDoug Rabson syslog(LOG_ERR, 716dfdcada3SDoug Rabson "cannot get local address for %s: %s", 717dfdcada3SDoug Rabson nconf->nc_netid, 718dfdcada3SDoug Rabson gai_strerror(aicode)); 719dfdcada3SDoug Rabson continue; 720dfdcada3SDoug Rabson } 721dfdcada3SDoug Rabson } 722dfdcada3SDoug Rabson } else { 723dfdcada3SDoug Rabson if ((aicode = getaddrinfo(hosts[nhostsbak], svcport_str, 724dfdcada3SDoug Rabson &hints, &res)) != 0) { 725dfdcada3SDoug Rabson syslog(LOG_ERR, 726dfdcada3SDoug Rabson "cannot get local address for %s: %s", 727dfdcada3SDoug Rabson nconf->nc_netid, gai_strerror(aicode)); 728dfdcada3SDoug Rabson continue; 729dfdcada3SDoug Rabson } 730dfdcada3SDoug Rabson } 731dfdcada3SDoug Rabson 732dfdcada3SDoug Rabson servaddr.len = servaddr.maxlen = res->ai_addr->sa_len; 733dfdcada3SDoug Rabson servaddr.buf = res->ai_addr; 734dfdcada3SDoug Rabson uaddr = taddr2uaddr(nconf, &servaddr); 735dfdcada3SDoug Rabson 736dfdcada3SDoug Rabson addrs = realloc(addrs, 2 * (naddrs + 1) * sizeof(char *)); 737dfdcada3SDoug Rabson if (!addrs) 738dfdcada3SDoug Rabson out_of_mem(); 739dfdcada3SDoug Rabson addrs[2 * naddrs] = strdup(nconf->nc_netid); 740dfdcada3SDoug Rabson addrs[2 * naddrs + 1] = uaddr; 741dfdcada3SDoug Rabson naddrs++; 742dfdcada3SDoug Rabson } /* end while */ 743dfdcada3SDoug Rabson } 744dfdcada3SDoug Rabson 7454945c132SAlfred Perlstein void 7464945c132SAlfred Perlstein sigalarm_handler(void) 7474945c132SAlfred Perlstein { 7484945c132SAlfred Perlstein 7494945c132SAlfred Perlstein grace_expired = 1; 7504945c132SAlfred Perlstein } 7514945c132SAlfred Perlstein 7524945c132SAlfred Perlstein void 7534945c132SAlfred Perlstein usage() 7544945c132SAlfred Perlstein { 7553efa83dcSDoug Rabson errx(1, "usage: rpc.lockd [-d <debuglevel>]" 756e56fbc5aSMatteo Riondato " [-g <grace period>] [-h <bindip>] [-p <port>]"); 7574945c132SAlfred Perlstein } 7584945c132SAlfred Perlstein 7594945c132SAlfred Perlstein /* 7604945c132SAlfred Perlstein * init_nsm -- 7614945c132SAlfred Perlstein * Reset the NSM state-of-the-world and acquire its state. 7624945c132SAlfred Perlstein */ 7634945c132SAlfred Perlstein void 7644945c132SAlfred Perlstein init_nsm(void) 7654945c132SAlfred Perlstein { 7664945c132SAlfred Perlstein enum clnt_stat ret; 7674945c132SAlfred Perlstein my_id id; 7684945c132SAlfred Perlstein sm_stat stat; 769e4b0fedeSAlfred Perlstein char name[] = "NFS NLM"; 770e4b0fedeSAlfred Perlstein char localhost[] = "localhost"; 7714945c132SAlfred Perlstein 7724945c132SAlfred Perlstein /* 7734945c132SAlfred Perlstein * !!! 7744945c132SAlfred Perlstein * The my_id structure isn't used by the SM_UNMON_ALL call, as far 7754945c132SAlfred Perlstein * as I know. Leave it empty for now. 7764945c132SAlfred Perlstein */ 7774945c132SAlfred Perlstein memset(&id, 0, sizeof(id)); 778e4b0fedeSAlfred Perlstein id.my_name = name; 7794945c132SAlfred Perlstein 7804945c132SAlfred Perlstein /* 7814945c132SAlfred Perlstein * !!! 7824945c132SAlfred Perlstein * The statd program must already be registered when lockd runs. 7834945c132SAlfred Perlstein */ 7844945c132SAlfred Perlstein do { 7854945c132SAlfred Perlstein ret = callrpc("localhost", SM_PROG, SM_VERS, SM_UNMON_ALL, 78675e40e46SPeter Wemm (xdrproc_t)xdr_my_id, &id, (xdrproc_t)xdr_sm_stat, &stat); 7874945c132SAlfred Perlstein if (ret == RPC_PROGUNAVAIL) { 7888ebcf97eSGuy Helmer syslog(LOG_WARNING, "%lu %s", SM_PROG, 7898ebcf97eSGuy Helmer clnt_sperrno(ret)); 7904945c132SAlfred Perlstein sleep(2); 7914945c132SAlfred Perlstein continue; 7924945c132SAlfred Perlstein } 7934945c132SAlfred Perlstein break; 7944945c132SAlfred Perlstein } while (0); 7954945c132SAlfred Perlstein 7964945c132SAlfred Perlstein if (ret != 0) { 7978ebcf97eSGuy Helmer syslog(LOG_ERR, "%lu %s", SM_PROG, clnt_sperrno(ret)); 7988ebcf97eSGuy Helmer exit(1); 7994945c132SAlfred Perlstein } 8004945c132SAlfred Perlstein 8014945c132SAlfred Perlstein nsm_state = stat.state; 8024945c132SAlfred Perlstein 8034945c132SAlfred Perlstein /* setup constant data for SM_MON calls */ 804e4b0fedeSAlfred Perlstein mon_host.mon_id.my_id.my_name = localhost; 8054945c132SAlfred Perlstein mon_host.mon_id.my_id.my_prog = NLM_PROG; 8064945c132SAlfred Perlstein mon_host.mon_id.my_id.my_vers = NLM_SM; 8074945c132SAlfred Perlstein mon_host.mon_id.my_id.my_proc = NLM_SM_NOTIFY; /* bsdi addition */ 8084945c132SAlfred Perlstein } 809e56fbc5aSMatteo Riondato 810e56fbc5aSMatteo Riondato /* 811e56fbc5aSMatteo Riondato * Out of memory, fatal 812e56fbc5aSMatteo Riondato */ 813e56fbc5aSMatteo Riondato void out_of_mem() 814e56fbc5aSMatteo Riondato { 815e56fbc5aSMatteo Riondato syslog(LOG_ERR, "out of memory"); 816e56fbc5aSMatteo Riondato exit(2); 817e56fbc5aSMatteo Riondato } 818