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; 83c675522fSDoug Rabson int kernel_lockd_client; 844945c132SAlfred Perlstein pid_t client_pid; 854945c132SAlfred Perlstein struct mon mon_host; 86e56fbc5aSMatteo Riondato char **hosts, *svcport_str = NULL; 87e56fbc5aSMatteo Riondato int nhosts = 0; 88e56fbc5aSMatteo Riondato int xcreated = 0; 89dfdcada3SDoug Rabson char **addrs; /* actually (netid, uaddr) pairs */ 90dfdcada3SDoug Rabson int naddrs; /* count of how many (netid, uaddr) pairs */ 914945c132SAlfred Perlstein 92e56fbc5aSMatteo Riondato void create_service(struct netconfig *nconf); 93dfdcada3SDoug Rabson void lookup_addresses(struct netconfig *nconf); 944945c132SAlfred Perlstein void init_nsm(void); 9533314abeSAlfred Perlstein void nlm_prog_0(struct svc_req *, SVCXPRT *); 9633314abeSAlfred Perlstein void nlm_prog_1(struct svc_req *, SVCXPRT *); 9733314abeSAlfred Perlstein void nlm_prog_3(struct svc_req *, SVCXPRT *); 9833314abeSAlfred Perlstein void nlm_prog_4(struct svc_req *, SVCXPRT *); 99e56fbc5aSMatteo Riondato void out_of_mem(void); 10033314abeSAlfred Perlstein void usage(void); 1014945c132SAlfred Perlstein 10233314abeSAlfred Perlstein void sigalarm_handler(void); 1034945c132SAlfred Perlstein 104dfdcada3SDoug Rabson /* 105dfdcada3SDoug Rabson * XXX move to some header file. 106dfdcada3SDoug Rabson */ 107dfdcada3SDoug Rabson #define _PATH_RPCLOCKDSOCK "/var/run/rpclockd.sock" 108dfdcada3SDoug Rabson 1094945c132SAlfred Perlstein int 110e56fbc5aSMatteo Riondato main(int argc, char **argv) 1114945c132SAlfred Perlstein { 112e56fbc5aSMatteo Riondato int ch, i, s; 113e56fbc5aSMatteo Riondato void *nc_handle; 114e56fbc5aSMatteo Riondato char *endptr, **hosts_bak; 1154945c132SAlfred Perlstein struct sigaction sigalarm; 1164945c132SAlfred Perlstein int grace_period = 30; 1174945c132SAlfred Perlstein struct netconfig *nconf; 118e56fbc5aSMatteo Riondato int have_v6 = 1; 119bcb53b16SMartin Blapp int maxrec = RPC_MAXDATASIZE; 12069f129c9SMatteo Riondato in_port_t svcport = 0; 1214945c132SAlfred Perlstein 122fa9d9930SDoug Rabson while ((ch = getopt(argc, argv, "d:g:h:p:")) != (-1)) { 1234945c132SAlfred Perlstein switch (ch) { 1244945c132SAlfred Perlstein case 'd': 1254945c132SAlfred Perlstein debug_level = atoi(optarg); 1264945c132SAlfred Perlstein if (!debug_level) { 1274945c132SAlfred Perlstein usage(); 1284945c132SAlfred Perlstein /* NOTREACHED */ 1294945c132SAlfred Perlstein } 1304945c132SAlfred Perlstein break; 1314945c132SAlfred Perlstein case 'g': 1324945c132SAlfred Perlstein grace_period = atoi(optarg); 1334945c132SAlfred Perlstein if (!grace_period) { 1344945c132SAlfred Perlstein usage(); 1354945c132SAlfred Perlstein /* NOTREACHED */ 1364945c132SAlfred Perlstein } 1374945c132SAlfred Perlstein break; 138e56fbc5aSMatteo Riondato case 'h': 139e56fbc5aSMatteo Riondato ++nhosts; 140e56fbc5aSMatteo Riondato hosts_bak = hosts; 141e56fbc5aSMatteo Riondato hosts_bak = realloc(hosts, nhosts * sizeof(char *)); 142e56fbc5aSMatteo Riondato if (hosts_bak == NULL) { 143e56fbc5aSMatteo Riondato if (hosts != NULL) { 144e56fbc5aSMatteo Riondato for (i = 0; i < nhosts; i++) 145e56fbc5aSMatteo Riondato free(hosts[i]); 146e56fbc5aSMatteo Riondato free(hosts); 147e56fbc5aSMatteo Riondato out_of_mem(); 148e56fbc5aSMatteo Riondato } 149e56fbc5aSMatteo Riondato } 150e56fbc5aSMatteo Riondato hosts = hosts_bak; 151e56fbc5aSMatteo Riondato hosts[nhosts - 1] = strdup(optarg); 152e56fbc5aSMatteo Riondato if (hosts[nhosts - 1] == NULL) { 153e56fbc5aSMatteo Riondato for (i = 0; i < (nhosts - 1); i++) 154e56fbc5aSMatteo Riondato free(hosts[i]); 155e56fbc5aSMatteo Riondato free(hosts); 156e56fbc5aSMatteo Riondato out_of_mem(); 157e56fbc5aSMatteo Riondato } 158e56fbc5aSMatteo Riondato 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 178fa9d9930SDoug Rabson kernel_lockd = FALSE; 179c675522fSDoug Rabson kernel_lockd_client = FALSE; 180fa9d9930SDoug Rabson if (modfind("nfslockd") < 0) { 181fa9d9930SDoug Rabson if (kldload("nfslockd") < 0) { 182fa9d9930SDoug Rabson fprintf(stderr, "Can't find or load kernel support for rpc.lockd - using non-kernel implementation\n"); 1833cba562fSDoug Rabson } else { 184fa9d9930SDoug Rabson kernel_lockd = TRUE; 1853cba562fSDoug Rabson } 186fa9d9930SDoug Rabson } else { 187fa9d9930SDoug Rabson kernel_lockd = TRUE; 188fa9d9930SDoug Rabson } 189c675522fSDoug Rabson if (kernel_lockd) { 190c675522fSDoug Rabson if (getosreldate() >= 800040) 191c675522fSDoug Rabson kernel_lockd_client = TRUE; 192c675522fSDoug Rabson } 193fa9d9930SDoug Rabson 1944945c132SAlfred Perlstein (void)rpcb_unset(NLM_PROG, NLM_SM, NULL); 1954945c132SAlfred Perlstein (void)rpcb_unset(NLM_PROG, NLM_VERS, NULL); 1964945c132SAlfred Perlstein (void)rpcb_unset(NLM_PROG, NLM_VERSX, NULL); 1974945c132SAlfred Perlstein (void)rpcb_unset(NLM_PROG, NLM_VERS4, NULL); 1984945c132SAlfred Perlstein 1994945c132SAlfred Perlstein /* 2004945c132SAlfred Perlstein * Check if IPv6 support is present. 2014945c132SAlfred Perlstein */ 2024945c132SAlfred Perlstein s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); 2034945c132SAlfred Perlstein if (s < 0) 204e56fbc5aSMatteo Riondato have_v6 = 0; 205e56fbc5aSMatteo Riondato else 2064945c132SAlfred Perlstein close(s); 20769f129c9SMatteo Riondato 208bcb53b16SMartin Blapp rpc_control(RPC_SVC_CONNMAXREC_SET, &maxrec); 209bcb53b16SMartin Blapp 210e56fbc5aSMatteo Riondato /* 211e56fbc5aSMatteo Riondato * If no hosts were specified, add a wildcard entry to bind to 212e56fbc5aSMatteo Riondato * INADDR_ANY. Otherwise make sure 127.0.0.1 and ::1 are added to the 213e56fbc5aSMatteo Riondato * list. 214e56fbc5aSMatteo Riondato */ 215e56fbc5aSMatteo Riondato if (nhosts == 0) { 216e56fbc5aSMatteo Riondato hosts = malloc(sizeof(char**)); 217e56fbc5aSMatteo Riondato if (hosts == NULL) 218e56fbc5aSMatteo Riondato out_of_mem(); 2194945c132SAlfred Perlstein 220e56fbc5aSMatteo Riondato hosts[0] = "*"; 221e56fbc5aSMatteo Riondato nhosts = 1; 22269f129c9SMatteo Riondato } else { 223e56fbc5aSMatteo Riondato hosts_bak = hosts; 224e56fbc5aSMatteo Riondato if (have_v6) { 225e56fbc5aSMatteo Riondato hosts_bak = realloc(hosts, (nhosts + 2) * 226e56fbc5aSMatteo Riondato sizeof(char *)); 227e56fbc5aSMatteo Riondato if (hosts_bak == NULL) { 228e56fbc5aSMatteo Riondato for (i = 0; i < nhosts; i++) 229e56fbc5aSMatteo Riondato free(hosts[i]); 230e56fbc5aSMatteo Riondato free(hosts); 231e56fbc5aSMatteo Riondato out_of_mem(); 232e56fbc5aSMatteo Riondato } else 233e56fbc5aSMatteo Riondato hosts = hosts_bak; 234e56fbc5aSMatteo Riondato 235e56fbc5aSMatteo Riondato nhosts += 2; 236e56fbc5aSMatteo Riondato hosts[nhosts - 2] = "::1"; 237e56fbc5aSMatteo Riondato } else { 238e56fbc5aSMatteo Riondato hosts_bak = realloc(hosts, (nhosts + 1) * sizeof(char *)); 239e56fbc5aSMatteo Riondato if (hosts_bak == NULL) { 240e56fbc5aSMatteo Riondato for (i = 0; i < nhosts; i++) 241e56fbc5aSMatteo Riondato free(hosts[i]); 242e56fbc5aSMatteo Riondato 243e56fbc5aSMatteo Riondato free(hosts); 244e56fbc5aSMatteo Riondato out_of_mem(); 245e56fbc5aSMatteo Riondato } else { 246e56fbc5aSMatteo Riondato nhosts += 1; 247e56fbc5aSMatteo Riondato hosts = hosts_bak; 248e56fbc5aSMatteo Riondato } 249e56fbc5aSMatteo Riondato } 250e56fbc5aSMatteo Riondato hosts[nhosts - 1] = "127.0.0.1"; 25169f129c9SMatteo Riondato } 25269f129c9SMatteo Riondato 253dfdcada3SDoug Rabson if (kernel_lockd) { 254c675522fSDoug Rabson if (!kernel_lockd_client) { 255dfdcada3SDoug Rabson /* 256c675522fSDoug Rabson * For the case where we have a kernel lockd but it 257c675522fSDoug Rabson * doesn't provide client locking, we run a cut-down 258c675522fSDoug Rabson * RPC service on a local-domain socket. The kernel's 259c675522fSDoug Rabson * RPC server will pass what it can't handle (mainly 260c675522fSDoug Rabson * client replies) down to us. 261dfdcada3SDoug Rabson */ 262dfdcada3SDoug Rabson struct sockaddr_un sun; 263dfdcada3SDoug Rabson int fd, oldmask; 264dfdcada3SDoug Rabson SVCXPRT *xprt; 265dfdcada3SDoug Rabson 266dfdcada3SDoug Rabson memset(&sun, 0, sizeof sun); 267dfdcada3SDoug Rabson sun.sun_family = AF_LOCAL; 268dfdcada3SDoug Rabson unlink(_PATH_RPCLOCKDSOCK); 269dfdcada3SDoug Rabson strcpy(sun.sun_path, _PATH_RPCLOCKDSOCK); 270dfdcada3SDoug Rabson sun.sun_len = SUN_LEN(&sun); 271dfdcada3SDoug Rabson fd = socket(AF_LOCAL, SOCK_STREAM, 0); 272dfdcada3SDoug Rabson if (!fd) { 273dfdcada3SDoug Rabson err(1, "Can't create local lockd socket"); 274dfdcada3SDoug Rabson } 275dfdcada3SDoug Rabson oldmask = umask(S_IXUSR|S_IRWXG|S_IRWXO); 276dfdcada3SDoug Rabson if (bind(fd, (struct sockaddr *) &sun, sun.sun_len) < 0) { 277dfdcada3SDoug Rabson err(1, "Can't bind local lockd socket"); 278dfdcada3SDoug Rabson } 279dfdcada3SDoug Rabson umask(oldmask); 280dfdcada3SDoug Rabson if (listen(fd, SOMAXCONN) < 0) { 281dfdcada3SDoug Rabson err(1, "Can't listen on local lockd socket"); 282dfdcada3SDoug Rabson } 283dfdcada3SDoug Rabson xprt = svc_vc_create(fd, RPC_MAXDATASIZE, RPC_MAXDATASIZE); 284dfdcada3SDoug Rabson if (!xprt) { 285dfdcada3SDoug Rabson err(1, "Can't create transport for local lockd socket"); 286dfdcada3SDoug Rabson } 287dfdcada3SDoug Rabson if (!svc_reg(xprt, NLM_PROG, NLM_VERS4, nlm_prog_4, NULL)) { 288dfdcada3SDoug Rabson err(1, "Can't register service for local lockd socket"); 289dfdcada3SDoug Rabson } 290c675522fSDoug Rabson } 291dfdcada3SDoug Rabson 292dfdcada3SDoug Rabson /* 293dfdcada3SDoug Rabson * We need to look up the addresses so that we can 294dfdcada3SDoug Rabson * hand uaddrs (ascii encoded address+port strings) to 295dfdcada3SDoug Rabson * the kernel. 296dfdcada3SDoug Rabson */ 297dfdcada3SDoug Rabson nc_handle = setnetconfig(); 298dfdcada3SDoug Rabson while ((nconf = getnetconfig(nc_handle))) { 299dfdcada3SDoug Rabson /* We want to listen only on udp6, tcp6, udp, tcp transports */ 300dfdcada3SDoug Rabson if (nconf->nc_flag & NC_VISIBLE) { 301dfdcada3SDoug Rabson /* Skip if there's no IPv6 support */ 302dfdcada3SDoug Rabson if (have_v6 == 0 && strcmp(nconf->nc_protofmly, "inet6") == 0) { 303dfdcada3SDoug Rabson /* DO NOTHING */ 304dfdcada3SDoug Rabson } else { 305dfdcada3SDoug Rabson lookup_addresses(nconf); 306dfdcada3SDoug Rabson } 307dfdcada3SDoug Rabson } 308dfdcada3SDoug Rabson } 309dfdcada3SDoug Rabson endnetconfig(nc_handle); 310dfdcada3SDoug Rabson } else { 311e56fbc5aSMatteo Riondato nc_handle = setnetconfig(); 312e56fbc5aSMatteo Riondato while ((nconf = getnetconfig(nc_handle))) { 313e56fbc5aSMatteo Riondato /* We want to listen only on udp6, tcp6, udp, tcp transports */ 314e56fbc5aSMatteo Riondato if (nconf->nc_flag & NC_VISIBLE) { 315e56fbc5aSMatteo Riondato /* Skip if there's no IPv6 support */ 316e56fbc5aSMatteo Riondato if (have_v6 == 0 && strcmp(nconf->nc_protofmly, "inet6") == 0) { 317e56fbc5aSMatteo Riondato /* DO NOTHING */ 318e56fbc5aSMatteo Riondato } else { 319e56fbc5aSMatteo Riondato create_service(nconf); 3204945c132SAlfred Perlstein } 3214945c132SAlfred Perlstein } 3224945c132SAlfred Perlstein } 323e56fbc5aSMatteo Riondato endnetconfig(nc_handle); 324dfdcada3SDoug Rabson } 3254945c132SAlfred Perlstein 3264945c132SAlfred Perlstein /* 3274945c132SAlfred Perlstein * Note that it is NOT sensible to run this program from inetd - the 3284945c132SAlfred Perlstein * protocol assumes that it will run immediately at boot time. 3294945c132SAlfred Perlstein */ 3303d81d1adSMichael Reifenberger if (daemon(0, debug_level > 0)) { 3314945c132SAlfred Perlstein err(1, "cannot fork"); 3324945c132SAlfred Perlstein /* NOTREACHED */ 3334945c132SAlfred Perlstein } 3344945c132SAlfred Perlstein 3354945c132SAlfred Perlstein openlog("rpc.lockd", 0, LOG_DAEMON); 3364945c132SAlfred Perlstein if (debug_level) 3374945c132SAlfred Perlstein syslog(LOG_INFO, "Starting, debug level %d", debug_level); 3384945c132SAlfred Perlstein else 3394945c132SAlfred Perlstein syslog(LOG_INFO, "Starting"); 3404945c132SAlfred Perlstein 3414945c132SAlfred Perlstein sigalarm.sa_handler = (sig_t) sigalarm_handler; 3424945c132SAlfred Perlstein sigemptyset(&sigalarm.sa_mask); 3434945c132SAlfred Perlstein sigalarm.sa_flags = SA_RESETHAND; /* should only happen once */ 3444945c132SAlfred Perlstein sigalarm.sa_flags |= SA_RESTART; 3454945c132SAlfred Perlstein if (sigaction(SIGALRM, &sigalarm, NULL) != 0) { 3464945c132SAlfred Perlstein syslog(LOG_WARNING, "sigaction(SIGALRM) failed: %s", 3474945c132SAlfred Perlstein strerror(errno)); 3484945c132SAlfred Perlstein exit(1); 3494945c132SAlfred Perlstein } 350dfdcada3SDoug Rabson 351dfdcada3SDoug Rabson if (kernel_lockd) { 352c675522fSDoug Rabson if (!kernel_lockd_client) { 353bbf7dc4cSDoug Rabson init_nsm(); 354dfdcada3SDoug Rabson client_pid = client_request(); 355dfdcada3SDoug Rabson 356dfdcada3SDoug Rabson /* 357dfdcada3SDoug Rabson * Create a child process to enter the kernel and then 358dfdcada3SDoug Rabson * wait for RPCs on our local domain socket. 359dfdcada3SDoug Rabson */ 360dfdcada3SDoug Rabson if (!fork()) 361c675522fSDoug Rabson nlm_syscall(debug_level, grace_period, 362c675522fSDoug Rabson naddrs, addrs); 363dfdcada3SDoug Rabson else 364dfdcada3SDoug Rabson svc_run(); 365dfdcada3SDoug Rabson } else { 366c675522fSDoug Rabson /* 367c675522fSDoug Rabson * The kernel lockd implementation provides 368c675522fSDoug Rabson * both client and server so we don't need to 369c675522fSDoug Rabson * do anything else. 370c675522fSDoug Rabson */ 371c675522fSDoug Rabson nlm_syscall(debug_level, grace_period, naddrs, addrs); 372c675522fSDoug Rabson } 373c675522fSDoug Rabson } else { 3744945c132SAlfred Perlstein grace_expired = 0; 37535a64c9fSThomas Quinot alarm(grace_period); 3764945c132SAlfred Perlstein 3774945c132SAlfred Perlstein init_nsm(); 3784945c132SAlfred Perlstein 3794945c132SAlfred Perlstein client_pid = client_request(); 3804945c132SAlfred Perlstein 3814945c132SAlfred Perlstein svc_run(); /* Should never return */ 382dfdcada3SDoug Rabson } 3834945c132SAlfred Perlstein exit(1); 3844945c132SAlfred Perlstein } 3854945c132SAlfred Perlstein 386e56fbc5aSMatteo Riondato /* 387e56fbc5aSMatteo Riondato * This routine creates and binds sockets on the appropriate 388e56fbc5aSMatteo Riondato * addresses. It gets called one time for each transport and 389e56fbc5aSMatteo Riondato * registrates the service with rpcbind on that trasport. 390e56fbc5aSMatteo Riondato */ 391e56fbc5aSMatteo Riondato void 392e56fbc5aSMatteo Riondato create_service(struct netconfig *nconf) 393e56fbc5aSMatteo Riondato { 394e56fbc5aSMatteo Riondato struct addrinfo hints, *res = NULL; 395e56fbc5aSMatteo Riondato struct sockaddr_in *sin; 396e56fbc5aSMatteo Riondato struct sockaddr_in6 *sin6; 397e56fbc5aSMatteo Riondato struct __rpc_sockinfo si; 398e56fbc5aSMatteo Riondato struct netbuf servaddr; 399e56fbc5aSMatteo Riondato SVCXPRT *transp = NULL; 400e56fbc5aSMatteo Riondato int aicode; 401e56fbc5aSMatteo Riondato int fd; 402e56fbc5aSMatteo Riondato int nhostsbak; 403e56fbc5aSMatteo Riondato int r; 404e56fbc5aSMatteo Riondato int registered = 0; 405e56fbc5aSMatteo Riondato u_int32_t host_addr[4]; /* IPv4 or IPv6 */ 406e56fbc5aSMatteo Riondato 407e56fbc5aSMatteo Riondato if ((nconf->nc_semantics != NC_TPI_CLTS) && 408e56fbc5aSMatteo Riondato (nconf->nc_semantics != NC_TPI_COTS) && 409e56fbc5aSMatteo Riondato (nconf->nc_semantics != NC_TPI_COTS_ORD)) 410e56fbc5aSMatteo Riondato return; /* not my type */ 411e56fbc5aSMatteo Riondato 412e56fbc5aSMatteo Riondato /* 413e56fbc5aSMatteo Riondato * XXX - using RPC library internal functions. 414e56fbc5aSMatteo Riondato */ 415e56fbc5aSMatteo Riondato if (!__rpc_nconf2sockinfo(nconf, &si)) { 416e56fbc5aSMatteo Riondato syslog(LOG_ERR, "cannot get information for %s", 417e56fbc5aSMatteo Riondato nconf->nc_netid); 418e56fbc5aSMatteo Riondato return; 419e56fbc5aSMatteo Riondato } 420e56fbc5aSMatteo Riondato 421e56fbc5aSMatteo Riondato /* Get rpc.statd's address on this transport */ 422e56fbc5aSMatteo Riondato memset(&hints, 0, sizeof hints); 423e56fbc5aSMatteo Riondato hints.ai_flags = AI_PASSIVE; 424e56fbc5aSMatteo Riondato hints.ai_family = si.si_af; 425e56fbc5aSMatteo Riondato hints.ai_socktype = si.si_socktype; 426e56fbc5aSMatteo Riondato hints.ai_protocol = si.si_proto; 427e56fbc5aSMatteo Riondato 428e56fbc5aSMatteo Riondato /* 429e56fbc5aSMatteo Riondato * Bind to specific IPs if asked to 430e56fbc5aSMatteo Riondato */ 431e56fbc5aSMatteo Riondato nhostsbak = nhosts; 432e56fbc5aSMatteo Riondato while (nhostsbak > 0) { 433e56fbc5aSMatteo Riondato --nhostsbak; 434e56fbc5aSMatteo Riondato 435e56fbc5aSMatteo Riondato /* 436e56fbc5aSMatteo Riondato * XXX - using RPC library internal functions. 437e56fbc5aSMatteo Riondato */ 438e56fbc5aSMatteo Riondato if ((fd = __rpc_nconf2fd(nconf)) < 0) { 439e56fbc5aSMatteo Riondato syslog(LOG_ERR, "cannot create socket for %s", 440e56fbc5aSMatteo Riondato nconf->nc_netid); 441e56fbc5aSMatteo Riondato continue; 442e56fbc5aSMatteo Riondato } 443e56fbc5aSMatteo Riondato 444e56fbc5aSMatteo Riondato switch (hints.ai_family) { 445e56fbc5aSMatteo Riondato case AF_INET: 446e56fbc5aSMatteo Riondato if (inet_pton(AF_INET, hosts[nhostsbak], 447e56fbc5aSMatteo Riondato host_addr) == 1) { 448e56fbc5aSMatteo Riondato hints.ai_flags &= AI_NUMERICHOST; 449e56fbc5aSMatteo Riondato } else { 450e56fbc5aSMatteo Riondato /* 451e56fbc5aSMatteo Riondato * Skip if we have an AF_INET6 address. 452e56fbc5aSMatteo Riondato */ 453e56fbc5aSMatteo Riondato if (inet_pton(AF_INET6, hosts[nhostsbak], 454e56fbc5aSMatteo Riondato host_addr) == 1) { 455e56fbc5aSMatteo Riondato close(fd); 456e56fbc5aSMatteo Riondato continue; 457e56fbc5aSMatteo Riondato } 458e56fbc5aSMatteo Riondato } 459e56fbc5aSMatteo Riondato break; 460e56fbc5aSMatteo Riondato case AF_INET6: 461e56fbc5aSMatteo Riondato if (inet_pton(AF_INET6, hosts[nhostsbak], 462e56fbc5aSMatteo Riondato host_addr) == 1) { 463e56fbc5aSMatteo Riondato hints.ai_flags &= AI_NUMERICHOST; 464e56fbc5aSMatteo Riondato } else { 465e56fbc5aSMatteo Riondato /* 466e56fbc5aSMatteo Riondato * Skip if we have an AF_INET address. 467e56fbc5aSMatteo Riondato */ 468e56fbc5aSMatteo Riondato if (inet_pton(AF_INET, hosts[nhostsbak], 469e56fbc5aSMatteo Riondato host_addr) == 1) { 470e56fbc5aSMatteo Riondato close(fd); 471e56fbc5aSMatteo Riondato continue; 472e56fbc5aSMatteo Riondato } 473e56fbc5aSMatteo Riondato } 474e56fbc5aSMatteo Riondato break; 475e56fbc5aSMatteo Riondato default: 476e56fbc5aSMatteo Riondato break; 477e56fbc5aSMatteo Riondato } 478e56fbc5aSMatteo Riondato 479e56fbc5aSMatteo Riondato /* 480e56fbc5aSMatteo Riondato * If no hosts were specified, just bind to INADDR_ANY 481e56fbc5aSMatteo Riondato */ 482e56fbc5aSMatteo Riondato if (strcmp("*", hosts[nhostsbak]) == 0) { 483e56fbc5aSMatteo Riondato if (svcport_str == NULL) { 484e56fbc5aSMatteo Riondato res = malloc(sizeof(struct addrinfo)); 485e56fbc5aSMatteo Riondato if (res == NULL) 486e56fbc5aSMatteo Riondato out_of_mem(); 487e56fbc5aSMatteo Riondato res->ai_flags = hints.ai_flags; 488e56fbc5aSMatteo Riondato res->ai_family = hints.ai_family; 489e56fbc5aSMatteo Riondato res->ai_protocol = hints.ai_protocol; 490e56fbc5aSMatteo Riondato switch (res->ai_family) { 491e56fbc5aSMatteo Riondato case AF_INET: 492e56fbc5aSMatteo Riondato sin = malloc(sizeof(struct sockaddr_in)); 493e56fbc5aSMatteo Riondato if (sin == NULL) 494e56fbc5aSMatteo Riondato out_of_mem(); 495e56fbc5aSMatteo Riondato sin->sin_family = AF_INET; 496e56fbc5aSMatteo Riondato sin->sin_port = htons(0); 497e56fbc5aSMatteo Riondato sin->sin_addr.s_addr = htonl(INADDR_ANY); 498e56fbc5aSMatteo Riondato res->ai_addr = (struct sockaddr*) sin; 499e56fbc5aSMatteo Riondato res->ai_addrlen = (socklen_t) 500e56fbc5aSMatteo Riondato sizeof(res->ai_addr); 501e56fbc5aSMatteo Riondato break; 502e56fbc5aSMatteo Riondato case AF_INET6: 503e56fbc5aSMatteo Riondato sin6 = malloc(sizeof(struct sockaddr_in6)); 50496e460ecSMatteo Riondato if (sin6 == NULL) 505e56fbc5aSMatteo Riondato out_of_mem(); 506e56fbc5aSMatteo Riondato sin6->sin6_family = AF_INET6; 507e56fbc5aSMatteo Riondato sin6->sin6_port = htons(0); 508e56fbc5aSMatteo Riondato sin6->sin6_addr = in6addr_any; 509e56fbc5aSMatteo Riondato res->ai_addr = (struct sockaddr*) sin6; 510e56fbc5aSMatteo Riondato res->ai_addrlen = (socklen_t) sizeof(res->ai_addr); 511e56fbc5aSMatteo Riondato break; 512e56fbc5aSMatteo Riondato default: 513e56fbc5aSMatteo Riondato break; 514e56fbc5aSMatteo Riondato } 515e56fbc5aSMatteo Riondato } else { 516e56fbc5aSMatteo Riondato if ((aicode = getaddrinfo(NULL, svcport_str, 517e56fbc5aSMatteo Riondato &hints, &res)) != 0) { 518e56fbc5aSMatteo Riondato syslog(LOG_ERR, 519e56fbc5aSMatteo Riondato "cannot get local address for %s: %s", 520e56fbc5aSMatteo Riondato nconf->nc_netid, 521e56fbc5aSMatteo Riondato gai_strerror(aicode)); 522e56fbc5aSMatteo Riondato continue; 523e56fbc5aSMatteo Riondato } 524e56fbc5aSMatteo Riondato } 525e56fbc5aSMatteo Riondato } else { 526e56fbc5aSMatteo Riondato if ((aicode = getaddrinfo(hosts[nhostsbak], svcport_str, 527e56fbc5aSMatteo Riondato &hints, &res)) != 0) { 528e56fbc5aSMatteo Riondato syslog(LOG_ERR, 529e56fbc5aSMatteo Riondato "cannot get local address for %s: %s", 530e56fbc5aSMatteo Riondato nconf->nc_netid, gai_strerror(aicode)); 531e56fbc5aSMatteo Riondato continue; 532e56fbc5aSMatteo Riondato } 533e56fbc5aSMatteo Riondato } 534e56fbc5aSMatteo Riondato 535e56fbc5aSMatteo Riondato r = bindresvport_sa(fd, res->ai_addr); 536e56fbc5aSMatteo Riondato if (r != 0) { 537e56fbc5aSMatteo Riondato syslog(LOG_ERR, "bindresvport_sa: %m"); 538e56fbc5aSMatteo Riondato exit(1); 539e56fbc5aSMatteo Riondato } 540e56fbc5aSMatteo Riondato 5410e7cce13SDoug Rabson if (nconf->nc_semantics != NC_TPI_CLTS) 5420e7cce13SDoug Rabson listen(fd, SOMAXCONN); 5430e7cce13SDoug Rabson 544e56fbc5aSMatteo Riondato transp = svc_tli_create(fd, nconf, NULL, 545e56fbc5aSMatteo Riondato RPC_MAXDATASIZE, RPC_MAXDATASIZE); 546e56fbc5aSMatteo Riondato 547e56fbc5aSMatteo Riondato if (transp != (SVCXPRT *) NULL) { 548e56fbc5aSMatteo Riondato if (!svc_reg(transp, NLM_PROG, NLM_SM, nlm_prog_0, 549e56fbc5aSMatteo Riondato NULL)) 550e56fbc5aSMatteo Riondato syslog(LOG_ERR, 551e56fbc5aSMatteo Riondato "can't register %s NLM_PROG, NLM_SM service", 552e56fbc5aSMatteo Riondato nconf->nc_netid); 553e56fbc5aSMatteo Riondato 554e56fbc5aSMatteo Riondato if (!svc_reg(transp, NLM_PROG, NLM_VERS, nlm_prog_1, 555e56fbc5aSMatteo Riondato NULL)) 556e56fbc5aSMatteo Riondato syslog(LOG_ERR, 557e56fbc5aSMatteo Riondato "can't register %s NLM_PROG, NLM_VERS service", 558e56fbc5aSMatteo Riondato nconf->nc_netid); 559e56fbc5aSMatteo Riondato 560e56fbc5aSMatteo Riondato if (!svc_reg(transp, NLM_PROG, NLM_VERSX, nlm_prog_3, 561e56fbc5aSMatteo Riondato NULL)) 562e56fbc5aSMatteo Riondato syslog(LOG_ERR, 563e56fbc5aSMatteo Riondato "can't register %s NLM_PROG, NLM_VERSX service", 564e56fbc5aSMatteo Riondato nconf->nc_netid); 565e56fbc5aSMatteo Riondato 566e56fbc5aSMatteo Riondato if (!svc_reg(transp, NLM_PROG, NLM_VERS4, nlm_prog_4, 567e56fbc5aSMatteo Riondato NULL)) 568e56fbc5aSMatteo Riondato syslog(LOG_ERR, 569e56fbc5aSMatteo Riondato "can't register %s NLM_PROG, NLM_VERS4 service", 570e56fbc5aSMatteo Riondato nconf->nc_netid); 571e56fbc5aSMatteo Riondato 572e56fbc5aSMatteo Riondato } else 573e56fbc5aSMatteo Riondato syslog(LOG_WARNING, "can't create %s services", 574e56fbc5aSMatteo Riondato nconf->nc_netid); 575e56fbc5aSMatteo Riondato 576e56fbc5aSMatteo Riondato if (registered == 0) { 577e56fbc5aSMatteo Riondato registered = 1; 578e56fbc5aSMatteo Riondato memset(&hints, 0, sizeof hints); 579e56fbc5aSMatteo Riondato hints.ai_flags = AI_PASSIVE; 580e56fbc5aSMatteo Riondato hints.ai_family = si.si_af; 581e56fbc5aSMatteo Riondato hints.ai_socktype = si.si_socktype; 582e56fbc5aSMatteo Riondato hints.ai_protocol = si.si_proto; 583e56fbc5aSMatteo Riondato 584e56fbc5aSMatteo Riondato if (svcport_str == NULL) { 585e56fbc5aSMatteo Riondato svcport_str = malloc(NI_MAXSERV * sizeof(char)); 586e56fbc5aSMatteo Riondato if (svcport_str == NULL) 587e56fbc5aSMatteo Riondato out_of_mem(); 588e56fbc5aSMatteo Riondato 589e56fbc5aSMatteo Riondato if (getnameinfo(res->ai_addr, 590e56fbc5aSMatteo Riondato res->ai_addr->sa_len, NULL, NI_MAXHOST, 591e56fbc5aSMatteo Riondato svcport_str, NI_MAXSERV * sizeof(char), 592e56fbc5aSMatteo Riondato NI_NUMERICHOST | NI_NUMERICSERV)) 593e56fbc5aSMatteo Riondato errx(1, "Cannot get port number"); 594e56fbc5aSMatteo Riondato } 595e56fbc5aSMatteo Riondato 596e56fbc5aSMatteo Riondato if((aicode = getaddrinfo(NULL, svcport_str, &hints, 597e56fbc5aSMatteo Riondato &res)) != 0) { 598e56fbc5aSMatteo Riondato syslog(LOG_ERR, "cannot get local address: %s", 599e56fbc5aSMatteo Riondato gai_strerror(aicode)); 600e56fbc5aSMatteo Riondato exit(1); 601e56fbc5aSMatteo Riondato } 602e56fbc5aSMatteo Riondato 603e56fbc5aSMatteo Riondato servaddr.buf = malloc(res->ai_addrlen); 604e56fbc5aSMatteo Riondato memcpy(servaddr.buf, res->ai_addr, res->ai_addrlen); 605e56fbc5aSMatteo Riondato servaddr.len = res->ai_addrlen; 606e56fbc5aSMatteo Riondato 607e56fbc5aSMatteo Riondato rpcb_set(NLM_PROG, NLM_SM, nconf, &servaddr); 608e56fbc5aSMatteo Riondato rpcb_set(NLM_PROG, NLM_VERS, nconf, &servaddr); 609e56fbc5aSMatteo Riondato rpcb_set(NLM_PROG, NLM_VERSX, nconf, &servaddr); 610e56fbc5aSMatteo Riondato rpcb_set(NLM_PROG, NLM_VERS4, nconf, &servaddr); 611e56fbc5aSMatteo Riondato 612e56fbc5aSMatteo Riondato xcreated++; 613e56fbc5aSMatteo Riondato freeaddrinfo(res); 614e56fbc5aSMatteo Riondato } 615e56fbc5aSMatteo Riondato } /* end while */ 616e56fbc5aSMatteo Riondato } 617e56fbc5aSMatteo Riondato 618dfdcada3SDoug Rabson /* 619dfdcada3SDoug Rabson * Look up addresses for the kernel to create transports for. 620dfdcada3SDoug Rabson */ 621dfdcada3SDoug Rabson void 622dfdcada3SDoug Rabson lookup_addresses(struct netconfig *nconf) 623dfdcada3SDoug Rabson { 624dfdcada3SDoug Rabson struct addrinfo hints, *res = NULL; 625dfdcada3SDoug Rabson struct sockaddr_in *sin; 626dfdcada3SDoug Rabson struct sockaddr_in6 *sin6; 627dfdcada3SDoug Rabson struct __rpc_sockinfo si; 628dfdcada3SDoug Rabson struct netbuf servaddr; 629dfdcada3SDoug Rabson SVCXPRT *transp = NULL; 630dfdcada3SDoug Rabson int aicode; 631dfdcada3SDoug Rabson int nhostsbak; 632dfdcada3SDoug Rabson int r; 633dfdcada3SDoug Rabson int registered = 0; 634dfdcada3SDoug Rabson u_int32_t host_addr[4]; /* IPv4 or IPv6 */ 635dfdcada3SDoug Rabson char *uaddr; 636dfdcada3SDoug Rabson 637dfdcada3SDoug Rabson if ((nconf->nc_semantics != NC_TPI_CLTS) && 638dfdcada3SDoug Rabson (nconf->nc_semantics != NC_TPI_COTS) && 639dfdcada3SDoug Rabson (nconf->nc_semantics != NC_TPI_COTS_ORD)) 640dfdcada3SDoug Rabson return; /* not my type */ 641dfdcada3SDoug Rabson 642dfdcada3SDoug Rabson /* 643dfdcada3SDoug Rabson * XXX - using RPC library internal functions. 644dfdcada3SDoug Rabson */ 645dfdcada3SDoug Rabson if (!__rpc_nconf2sockinfo(nconf, &si)) { 646dfdcada3SDoug Rabson syslog(LOG_ERR, "cannot get information for %s", 647dfdcada3SDoug Rabson nconf->nc_netid); 648dfdcada3SDoug Rabson return; 649dfdcada3SDoug Rabson } 650dfdcada3SDoug Rabson 651dfdcada3SDoug Rabson /* Get rpc.statd's address on this transport */ 652dfdcada3SDoug Rabson memset(&hints, 0, sizeof hints); 653dfdcada3SDoug Rabson hints.ai_flags = AI_PASSIVE; 654dfdcada3SDoug Rabson hints.ai_family = si.si_af; 655dfdcada3SDoug Rabson hints.ai_socktype = si.si_socktype; 656dfdcada3SDoug Rabson hints.ai_protocol = si.si_proto; 657dfdcada3SDoug Rabson 658dfdcada3SDoug Rabson /* 659dfdcada3SDoug Rabson * Bind to specific IPs if asked to 660dfdcada3SDoug Rabson */ 661dfdcada3SDoug Rabson nhostsbak = nhosts; 662dfdcada3SDoug Rabson while (nhostsbak > 0) { 663dfdcada3SDoug Rabson --nhostsbak; 664dfdcada3SDoug Rabson 665dfdcada3SDoug Rabson switch (hints.ai_family) { 666dfdcada3SDoug Rabson case AF_INET: 667dfdcada3SDoug Rabson if (inet_pton(AF_INET, hosts[nhostsbak], 668dfdcada3SDoug Rabson host_addr) == 1) { 669dfdcada3SDoug Rabson hints.ai_flags &= AI_NUMERICHOST; 670dfdcada3SDoug Rabson } else { 671dfdcada3SDoug Rabson /* 672dfdcada3SDoug Rabson * Skip if we have an AF_INET6 address. 673dfdcada3SDoug Rabson */ 674dfdcada3SDoug Rabson if (inet_pton(AF_INET6, hosts[nhostsbak], 675dfdcada3SDoug Rabson host_addr) == 1) { 676dfdcada3SDoug Rabson continue; 677dfdcada3SDoug Rabson } 678dfdcada3SDoug Rabson } 679dfdcada3SDoug Rabson break; 680dfdcada3SDoug Rabson case AF_INET6: 681dfdcada3SDoug Rabson if (inet_pton(AF_INET6, hosts[nhostsbak], 682dfdcada3SDoug Rabson host_addr) == 1) { 683dfdcada3SDoug Rabson hints.ai_flags &= AI_NUMERICHOST; 684dfdcada3SDoug Rabson } else { 685dfdcada3SDoug Rabson /* 686dfdcada3SDoug Rabson * Skip if we have an AF_INET address. 687dfdcada3SDoug Rabson */ 688dfdcada3SDoug Rabson if (inet_pton(AF_INET, hosts[nhostsbak], 689dfdcada3SDoug Rabson host_addr) == 1) { 690dfdcada3SDoug Rabson continue; 691dfdcada3SDoug Rabson } 692dfdcada3SDoug Rabson } 693dfdcada3SDoug Rabson break; 694dfdcada3SDoug Rabson default: 695dfdcada3SDoug Rabson break; 696dfdcada3SDoug Rabson } 697dfdcada3SDoug Rabson 698dfdcada3SDoug Rabson /* 699dfdcada3SDoug Rabson * If no hosts were specified, just bind to INADDR_ANY 700dfdcada3SDoug Rabson */ 701dfdcada3SDoug Rabson if (strcmp("*", hosts[nhostsbak]) == 0) { 702dfdcada3SDoug Rabson if (svcport_str == NULL) { 703dfdcada3SDoug Rabson res = malloc(sizeof(struct addrinfo)); 704dfdcada3SDoug Rabson if (res == NULL) 705dfdcada3SDoug Rabson out_of_mem(); 706dfdcada3SDoug Rabson res->ai_flags = hints.ai_flags; 707dfdcada3SDoug Rabson res->ai_family = hints.ai_family; 708dfdcada3SDoug Rabson res->ai_protocol = hints.ai_protocol; 709dfdcada3SDoug Rabson switch (res->ai_family) { 710dfdcada3SDoug Rabson case AF_INET: 711dfdcada3SDoug Rabson sin = malloc(sizeof(struct sockaddr_in)); 712dfdcada3SDoug Rabson if (sin == NULL) 713dfdcada3SDoug Rabson out_of_mem(); 714dfdcada3SDoug Rabson sin->sin_family = AF_INET; 715dfdcada3SDoug Rabson sin->sin_port = htons(0); 716dfdcada3SDoug Rabson sin->sin_addr.s_addr = htonl(INADDR_ANY); 717dfdcada3SDoug Rabson res->ai_addr = (struct sockaddr*) sin; 718dfdcada3SDoug Rabson res->ai_addrlen = (socklen_t) 719dfdcada3SDoug Rabson sizeof(res->ai_addr); 720dfdcada3SDoug Rabson break; 721dfdcada3SDoug Rabson case AF_INET6: 722dfdcada3SDoug Rabson sin6 = malloc(sizeof(struct sockaddr_in6)); 723dfdcada3SDoug Rabson if (sin6 == NULL) 724dfdcada3SDoug Rabson out_of_mem(); 725dfdcada3SDoug Rabson sin6->sin6_family = AF_INET6; 726dfdcada3SDoug Rabson sin6->sin6_port = htons(0); 727dfdcada3SDoug Rabson sin6->sin6_addr = in6addr_any; 728dfdcada3SDoug Rabson res->ai_addr = (struct sockaddr*) sin6; 729dfdcada3SDoug Rabson res->ai_addrlen = (socklen_t) sizeof(res->ai_addr); 730dfdcada3SDoug Rabson break; 731dfdcada3SDoug Rabson default: 732dfdcada3SDoug Rabson break; 733dfdcada3SDoug Rabson } 734dfdcada3SDoug Rabson } else { 735dfdcada3SDoug Rabson if ((aicode = getaddrinfo(NULL, svcport_str, 736dfdcada3SDoug Rabson &hints, &res)) != 0) { 737dfdcada3SDoug Rabson syslog(LOG_ERR, 738dfdcada3SDoug Rabson "cannot get local address for %s: %s", 739dfdcada3SDoug Rabson nconf->nc_netid, 740dfdcada3SDoug Rabson gai_strerror(aicode)); 741dfdcada3SDoug Rabson continue; 742dfdcada3SDoug Rabson } 743dfdcada3SDoug Rabson } 744dfdcada3SDoug Rabson } else { 745dfdcada3SDoug Rabson if ((aicode = getaddrinfo(hosts[nhostsbak], svcport_str, 746dfdcada3SDoug Rabson &hints, &res)) != 0) { 747dfdcada3SDoug Rabson syslog(LOG_ERR, 748dfdcada3SDoug Rabson "cannot get local address for %s: %s", 749dfdcada3SDoug Rabson nconf->nc_netid, gai_strerror(aicode)); 750dfdcada3SDoug Rabson continue; 751dfdcada3SDoug Rabson } 752dfdcada3SDoug Rabson } 753dfdcada3SDoug Rabson 754dfdcada3SDoug Rabson servaddr.len = servaddr.maxlen = res->ai_addr->sa_len; 755dfdcada3SDoug Rabson servaddr.buf = res->ai_addr; 756dfdcada3SDoug Rabson uaddr = taddr2uaddr(nconf, &servaddr); 757dfdcada3SDoug Rabson 758dfdcada3SDoug Rabson addrs = realloc(addrs, 2 * (naddrs + 1) * sizeof(char *)); 759dfdcada3SDoug Rabson if (!addrs) 760dfdcada3SDoug Rabson out_of_mem(); 761dfdcada3SDoug Rabson addrs[2 * naddrs] = strdup(nconf->nc_netid); 762dfdcada3SDoug Rabson addrs[2 * naddrs + 1] = uaddr; 763dfdcada3SDoug Rabson naddrs++; 764dfdcada3SDoug Rabson } /* end while */ 765dfdcada3SDoug Rabson } 766dfdcada3SDoug Rabson 7674945c132SAlfred Perlstein void 7684945c132SAlfred Perlstein sigalarm_handler(void) 7694945c132SAlfred Perlstein { 7704945c132SAlfred Perlstein 7714945c132SAlfred Perlstein grace_expired = 1; 7724945c132SAlfred Perlstein } 7734945c132SAlfred Perlstein 7744945c132SAlfred Perlstein void 7754945c132SAlfred Perlstein usage() 7764945c132SAlfred Perlstein { 7773efa83dcSDoug Rabson errx(1, "usage: rpc.lockd [-d <debuglevel>]" 778e56fbc5aSMatteo Riondato " [-g <grace period>] [-h <bindip>] [-p <port>]"); 7794945c132SAlfred Perlstein } 7804945c132SAlfred Perlstein 7814945c132SAlfred Perlstein /* 7824945c132SAlfred Perlstein * init_nsm -- 7834945c132SAlfred Perlstein * Reset the NSM state-of-the-world and acquire its state. 7844945c132SAlfred Perlstein */ 7854945c132SAlfred Perlstein void 7864945c132SAlfred Perlstein init_nsm(void) 7874945c132SAlfred Perlstein { 7884945c132SAlfred Perlstein enum clnt_stat ret; 7894945c132SAlfred Perlstein my_id id; 7904945c132SAlfred Perlstein sm_stat stat; 791e4b0fedeSAlfred Perlstein char name[] = "NFS NLM"; 792e4b0fedeSAlfred Perlstein char localhost[] = "localhost"; 7934945c132SAlfred Perlstein 7944945c132SAlfred Perlstein /* 7954945c132SAlfred Perlstein * !!! 7964945c132SAlfred Perlstein * The my_id structure isn't used by the SM_UNMON_ALL call, as far 7974945c132SAlfred Perlstein * as I know. Leave it empty for now. 7984945c132SAlfred Perlstein */ 7994945c132SAlfred Perlstein memset(&id, 0, sizeof(id)); 800e4b0fedeSAlfred Perlstein id.my_name = name; 8014945c132SAlfred Perlstein 8024945c132SAlfred Perlstein /* 8034945c132SAlfred Perlstein * !!! 8044945c132SAlfred Perlstein * The statd program must already be registered when lockd runs. 8054945c132SAlfred Perlstein */ 8064945c132SAlfred Perlstein do { 8074945c132SAlfred Perlstein ret = callrpc("localhost", SM_PROG, SM_VERS, SM_UNMON_ALL, 80875e40e46SPeter Wemm (xdrproc_t)xdr_my_id, &id, (xdrproc_t)xdr_sm_stat, &stat); 8094945c132SAlfred Perlstein if (ret == RPC_PROGUNAVAIL) { 8108ebcf97eSGuy Helmer syslog(LOG_WARNING, "%lu %s", SM_PROG, 8118ebcf97eSGuy Helmer clnt_sperrno(ret)); 8124945c132SAlfred Perlstein sleep(2); 8134945c132SAlfred Perlstein continue; 8144945c132SAlfred Perlstein } 8154945c132SAlfred Perlstein break; 8164945c132SAlfred Perlstein } while (0); 8174945c132SAlfred Perlstein 8184945c132SAlfred Perlstein if (ret != 0) { 8198ebcf97eSGuy Helmer syslog(LOG_ERR, "%lu %s", SM_PROG, clnt_sperrno(ret)); 8208ebcf97eSGuy Helmer exit(1); 8214945c132SAlfred Perlstein } 8224945c132SAlfred Perlstein 8234945c132SAlfred Perlstein nsm_state = stat.state; 8244945c132SAlfred Perlstein 8254945c132SAlfred Perlstein /* setup constant data for SM_MON calls */ 826e4b0fedeSAlfred Perlstein mon_host.mon_id.my_id.my_name = localhost; 8274945c132SAlfred Perlstein mon_host.mon_id.my_id.my_prog = NLM_PROG; 8284945c132SAlfred Perlstein mon_host.mon_id.my_id.my_vers = NLM_SM; 8294945c132SAlfred Perlstein mon_host.mon_id.my_id.my_proc = NLM_SM_NOTIFY; /* bsdi addition */ 8304945c132SAlfred Perlstein } 831e56fbc5aSMatteo Riondato 832e56fbc5aSMatteo Riondato /* 833e56fbc5aSMatteo Riondato * Out of memory, fatal 834e56fbc5aSMatteo Riondato */ 835e56fbc5aSMatteo Riondato void out_of_mem() 836e56fbc5aSMatteo Riondato { 837e56fbc5aSMatteo Riondato syslog(LOG_ERR, "out of memory"); 838e56fbc5aSMatteo Riondato exit(2); 839e56fbc5aSMatteo Riondato } 840