Deleted Added
full compact
lockd.c (173411) lockd.c (177633)
1/* $NetBSD: lockd.c,v 1.7 2000/08/12 18:08:44 thorpej Exp $ */
1/* $NetBSD: lockd.c,v 1.7 2000/08/12 18:08:44 thorpej Exp $ */
2/* $FreeBSD: head/usr.sbin/rpc.lockd/lockd.c 173411 2007-11-07 10:21:36Z matteo $ */
2/* $FreeBSD: head/usr.sbin/rpc.lockd/lockd.c 177633 2008-03-26 15:23:12Z dfr $ */
3
4/*
5 * Copyright (c) 1995
6 * A.R. Gordon (andrew.gordon@net-tel.co.uk). All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:

--- 32 unchanged lines hidden (view full) ---

43 * main() function for NFS lock daemon. Most of the code in this
44 * file was generated by running rpcgen /usr/include/rpcsvc/nlm_prot.x.
45 *
46 * The actual program logic is in the file lock_proc.c
47 */
48
49#include <sys/types.h>
50#include <sys/socket.h>
3
4/*
5 * Copyright (c) 1995
6 * A.R. Gordon (andrew.gordon@net-tel.co.uk). All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:

--- 32 unchanged lines hidden (view full) ---

43 * main() function for NFS lock daemon. Most of the code in this
44 * file was generated by running rpcgen /usr/include/rpcsvc/nlm_prot.x.
45 *
46 * The actual program logic is in the file lock_proc.c
47 */
48
49#include <sys/types.h>
50#include <sys/socket.h>
51#include <sys/stat.h>
51
52#include <netinet/in.h>
53#include <arpa/inet.h>
54
55#include <err.h>
56#include <stdio.h>
57#include <stdlib.h>
58#include <errno.h>

--- 12 unchanged lines hidden (view full) ---

71#include "lockd.h"
72#include <rpcsvc/nlm_prot.h>
73
74int debug_level = 0; /* 0 = no debugging syslog() calls */
75int _rpcsvcdirty = 0;
76
77int grace_expired;
78int nsm_state;
52
53#include <netinet/in.h>
54#include <arpa/inet.h>
55
56#include <err.h>
57#include <stdio.h>
58#include <stdlib.h>
59#include <errno.h>

--- 12 unchanged lines hidden (view full) ---

72#include "lockd.h"
73#include <rpcsvc/nlm_prot.h>
74
75int debug_level = 0; /* 0 = no debugging syslog() calls */
76int _rpcsvcdirty = 0;
77
78int grace_expired;
79int nsm_state;
80int kernel_lockd;
79pid_t client_pid;
80struct mon mon_host;
81char **hosts, *svcport_str = NULL;
82int nhosts = 0;
83int xcreated = 0;
81pid_t client_pid;
82struct mon mon_host;
83char **hosts, *svcport_str = NULL;
84int nhosts = 0;
85int xcreated = 0;
86char **addrs; /* actually (netid, uaddr) pairs */
87int naddrs; /* count of how many (netid, uaddr) pairs */
84
85void create_service(struct netconfig *nconf);
88
89void create_service(struct netconfig *nconf);
90void lookup_addresses(struct netconfig *nconf);
86void init_nsm(void);
87void nlm_prog_0(struct svc_req *, SVCXPRT *);
88void nlm_prog_1(struct svc_req *, SVCXPRT *);
89void nlm_prog_3(struct svc_req *, SVCXPRT *);
90void nlm_prog_4(struct svc_req *, SVCXPRT *);
91void out_of_mem(void);
92void usage(void);
93
94void sigalarm_handler(void);
95
91void init_nsm(void);
92void nlm_prog_0(struct svc_req *, SVCXPRT *);
93void nlm_prog_1(struct svc_req *, SVCXPRT *);
94void nlm_prog_3(struct svc_req *, SVCXPRT *);
95void nlm_prog_4(struct svc_req *, SVCXPRT *);
96void out_of_mem(void);
97void usage(void);
98
99void sigalarm_handler(void);
100
101/*
102 * XXX move to some header file.
103 */
104#define _PATH_RPCLOCKDSOCK "/var/run/rpclockd.sock"
105
96int
97main(int argc, char **argv)
98{
99 int ch, i, s;
100 void *nc_handle;
101 char *endptr, **hosts_bak;
102 struct sigaction sigalarm;
103 int grace_period = 30;
104 struct netconfig *nconf;
105 int have_v6 = 1;
106 int maxrec = RPC_MAXDATASIZE;
107 in_port_t svcport = 0;
108
106int
107main(int argc, char **argv)
108{
109 int ch, i, s;
110 void *nc_handle;
111 char *endptr, **hosts_bak;
112 struct sigaction sigalarm;
113 int grace_period = 30;
114 struct netconfig *nconf;
115 int have_v6 = 1;
116 int maxrec = RPC_MAXDATASIZE;
117 in_port_t svcport = 0;
118
109 while ((ch = getopt(argc, argv, "d:g:h:p:")) != (-1)) {
119 while ((ch = getopt(argc, argv, "d:g:h:kp:")) != (-1)) {
110 switch (ch) {
111 case 'd':
112 debug_level = atoi(optarg);
113 if (!debug_level) {
114 usage();
115 /* NOTREACHED */
116 }
117 break;

--- 20 unchanged lines hidden (view full) ---

138 hosts[nhosts - 1] = strdup(optarg);
139 if (hosts[nhosts - 1] == NULL) {
140 for (i = 0; i < (nhosts - 1); i++)
141 free(hosts[i]);
142 free(hosts);
143 out_of_mem();
144 }
145 break;
120 switch (ch) {
121 case 'd':
122 debug_level = atoi(optarg);
123 if (!debug_level) {
124 usage();
125 /* NOTREACHED */
126 }
127 break;

--- 20 unchanged lines hidden (view full) ---

148 hosts[nhosts - 1] = strdup(optarg);
149 if (hosts[nhosts - 1] == NULL) {
150 for (i = 0; i < (nhosts - 1); i++)
151 free(hosts[i]);
152 free(hosts);
153 out_of_mem();
154 }
155 break;
156 case 'k':
157 kernel_lockd = TRUE;
158 break;
146 case 'p':
147 endptr = NULL;
148 svcport = (in_port_t)strtoul(optarg, &endptr, 10);
149 if (endptr == NULL || *endptr != '\0' ||
150 svcport == 0 || svcport >= IPPORT_MAX)
151 usage();
152 svcport_str = strdup(optarg);
153 break;

--- 62 unchanged lines hidden (view full) ---

216 } else {
217 nhosts += 1;
218 hosts = hosts_bak;
219 }
220 }
221 hosts[nhosts - 1] = "127.0.0.1";
222 }
223
159 case 'p':
160 endptr = NULL;
161 svcport = (in_port_t)strtoul(optarg, &endptr, 10);
162 if (endptr == NULL || *endptr != '\0' ||
163 svcport == 0 || svcport >= IPPORT_MAX)
164 usage();
165 svcport_str = strdup(optarg);
166 break;

--- 62 unchanged lines hidden (view full) ---

229 } else {
230 nhosts += 1;
231 hosts = hosts_bak;
232 }
233 }
234 hosts[nhosts - 1] = "127.0.0.1";
235 }
236
224 nc_handle = setnetconfig();
225 while ((nconf = getnetconfig(nc_handle))) {
226 /* We want to listen only on udp6, tcp6, udp, tcp transports */
227 if (nconf->nc_flag & NC_VISIBLE) {
228 /* Skip if there's no IPv6 support */
229 if (have_v6 == 0 && strcmp(nconf->nc_protofmly, "inet6") == 0) {
230 /* DO NOTHING */
231 } else {
232 create_service(nconf);
237 if (kernel_lockd) {
238 /*
239 * For the kernel lockd case, we run a cut-down RPC
240 * service on a local-domain socket. The kernel's RPC
241 * server will pass what it can't handle (mainly
242 * client replies) down to us. This can go away
243 * entirely if/when we move the client side of NFS
244 * locking into the kernel.
245 */
246 struct sockaddr_un sun;
247 int fd, oldmask;
248 SVCXPRT *xprt;
249
250 memset(&sun, 0, sizeof sun);
251 sun.sun_family = AF_LOCAL;
252 unlink(_PATH_RPCLOCKDSOCK);
253 strcpy(sun.sun_path, _PATH_RPCLOCKDSOCK);
254 sun.sun_len = SUN_LEN(&sun);
255 fd = socket(AF_LOCAL, SOCK_STREAM, 0);
256 if (!fd) {
257 err(1, "Can't create local lockd socket");
258 }
259 oldmask = umask(S_IXUSR|S_IRWXG|S_IRWXO);
260 if (bind(fd, (struct sockaddr *) &sun, sun.sun_len) < 0) {
261 err(1, "Can't bind local lockd socket");
262 }
263 umask(oldmask);
264 if (listen(fd, SOMAXCONN) < 0) {
265 err(1, "Can't listen on local lockd socket");
266 }
267 xprt = svc_vc_create(fd, RPC_MAXDATASIZE, RPC_MAXDATASIZE);
268 if (!xprt) {
269 err(1, "Can't create transport for local lockd socket");
270 }
271 if (!svc_reg(xprt, NLM_PROG, NLM_VERS4, nlm_prog_4, NULL)) {
272 err(1, "Can't register service for local lockd socket");
273 }
274
275 /*
276 * We need to look up the addresses so that we can
277 * hand uaddrs (ascii encoded address+port strings) to
278 * the kernel.
279 */
280 nc_handle = setnetconfig();
281 while ((nconf = getnetconfig(nc_handle))) {
282 /* We want to listen only on udp6, tcp6, udp, tcp transports */
283 if (nconf->nc_flag & NC_VISIBLE) {
284 /* Skip if there's no IPv6 support */
285 if (have_v6 == 0 && strcmp(nconf->nc_protofmly, "inet6") == 0) {
286 /* DO NOTHING */
287 } else {
288 lookup_addresses(nconf);
289 }
233 }
234 }
290 }
291 }
292 endnetconfig(nc_handle);
293 } else {
294 nc_handle = setnetconfig();
295 while ((nconf = getnetconfig(nc_handle))) {
296 /* We want to listen only on udp6, tcp6, udp, tcp transports */
297 if (nconf->nc_flag & NC_VISIBLE) {
298 /* Skip if there's no IPv6 support */
299 if (have_v6 == 0 && strcmp(nconf->nc_protofmly, "inet6") == 0) {
300 /* DO NOTHING */
301 } else {
302 create_service(nconf);
303 }
304 }
305 }
306 endnetconfig(nc_handle);
235 }
307 }
236 endnetconfig(nc_handle);
237
238 /*
239 * Note that it is NOT sensible to run this program from inetd - the
240 * protocol assumes that it will run immediately at boot time.
241 */
242 if (daemon(0, debug_level > 0)) {
243 err(1, "cannot fork");
244 /* NOTREACHED */

--- 9 unchanged lines hidden (view full) ---

254 sigemptyset(&sigalarm.sa_mask);
255 sigalarm.sa_flags = SA_RESETHAND; /* should only happen once */
256 sigalarm.sa_flags |= SA_RESTART;
257 if (sigaction(SIGALRM, &sigalarm, NULL) != 0) {
258 syslog(LOG_WARNING, "sigaction(SIGALRM) failed: %s",
259 strerror(errno));
260 exit(1);
261 }
308
309 /*
310 * Note that it is NOT sensible to run this program from inetd - the
311 * protocol assumes that it will run immediately at boot time.
312 */
313 if (daemon(0, debug_level > 0)) {
314 err(1, "cannot fork");
315 /* NOTREACHED */

--- 9 unchanged lines hidden (view full) ---

325 sigemptyset(&sigalarm.sa_mask);
326 sigalarm.sa_flags = SA_RESETHAND; /* should only happen once */
327 sigalarm.sa_flags |= SA_RESTART;
328 if (sigaction(SIGALRM, &sigalarm, NULL) != 0) {
329 syslog(LOG_WARNING, "sigaction(SIGALRM) failed: %s",
330 strerror(errno));
331 exit(1);
332 }
262 grace_expired = 0;
263 alarm(grace_period);
264
333
265 init_nsm();
334 if (kernel_lockd) {
335 client_pid = client_request();
266
336
267 client_pid = client_request();
337 /*
338 * Create a child process to enter the kernel and then
339 * wait for RPCs on our local domain socket.
340 */
341 if (!fork())
342 nlm_syscall(debug_level, grace_period, naddrs, addrs);
343 else
344 svc_run();
345 } else {
346 grace_expired = 0;
347 alarm(grace_period);
268
348
269 svc_run(); /* Should never return */
349 init_nsm();
350
351 client_pid = client_request();
352
353 svc_run(); /* Should never return */
354 }
270 exit(1);
271}
272
273/*
274 * This routine creates and binds sockets on the appropriate
275 * addresses. It gets called one time for each transport and
276 * registrates the service with rpcbind on that trasport.
277 */

--- 216 unchanged lines hidden (view full) ---

494 rpcb_set(NLM_PROG, NLM_VERS4, nconf, &servaddr);
495
496 xcreated++;
497 freeaddrinfo(res);
498 }
499 } /* end while */
500}
501
355 exit(1);
356}
357
358/*
359 * This routine creates and binds sockets on the appropriate
360 * addresses. It gets called one time for each transport and
361 * registrates the service with rpcbind on that trasport.
362 */

--- 216 unchanged lines hidden (view full) ---

579 rpcb_set(NLM_PROG, NLM_VERS4, nconf, &servaddr);
580
581 xcreated++;
582 freeaddrinfo(res);
583 }
584 } /* end while */
585}
586
587/*
588 * Look up addresses for the kernel to create transports for.
589 */
502void
590void
591lookup_addresses(struct netconfig *nconf)
592{
593 struct addrinfo hints, *res = NULL;
594 struct sockaddr_in *sin;
595 struct sockaddr_in6 *sin6;
596 struct __rpc_sockinfo si;
597 struct netbuf servaddr;
598 SVCXPRT *transp = NULL;
599 int aicode;
600 int nhostsbak;
601 int r;
602 int registered = 0;
603 u_int32_t host_addr[4]; /* IPv4 or IPv6 */
604 char *uaddr;
605
606 if ((nconf->nc_semantics != NC_TPI_CLTS) &&
607 (nconf->nc_semantics != NC_TPI_COTS) &&
608 (nconf->nc_semantics != NC_TPI_COTS_ORD))
609 return; /* not my type */
610
611 /*
612 * XXX - using RPC library internal functions.
613 */
614 if (!__rpc_nconf2sockinfo(nconf, &si)) {
615 syslog(LOG_ERR, "cannot get information for %s",
616 nconf->nc_netid);
617 return;
618 }
619
620 /* Get rpc.statd's address on this transport */
621 memset(&hints, 0, sizeof hints);
622 hints.ai_flags = AI_PASSIVE;
623 hints.ai_family = si.si_af;
624 hints.ai_socktype = si.si_socktype;
625 hints.ai_protocol = si.si_proto;
626
627 /*
628 * Bind to specific IPs if asked to
629 */
630 nhostsbak = nhosts;
631 while (nhostsbak > 0) {
632 --nhostsbak;
633
634 switch (hints.ai_family) {
635 case AF_INET:
636 if (inet_pton(AF_INET, hosts[nhostsbak],
637 host_addr) == 1) {
638 hints.ai_flags &= AI_NUMERICHOST;
639 } else {
640 /*
641 * Skip if we have an AF_INET6 address.
642 */
643 if (inet_pton(AF_INET6, hosts[nhostsbak],
644 host_addr) == 1) {
645 continue;
646 }
647 }
648 break;
649 case AF_INET6:
650 if (inet_pton(AF_INET6, hosts[nhostsbak],
651 host_addr) == 1) {
652 hints.ai_flags &= AI_NUMERICHOST;
653 } else {
654 /*
655 * Skip if we have an AF_INET address.
656 */
657 if (inet_pton(AF_INET, hosts[nhostsbak],
658 host_addr) == 1) {
659 continue;
660 }
661 }
662 break;
663 default:
664 break;
665 }
666
667 /*
668 * If no hosts were specified, just bind to INADDR_ANY
669 */
670 if (strcmp("*", hosts[nhostsbak]) == 0) {
671 if (svcport_str == NULL) {
672 res = malloc(sizeof(struct addrinfo));
673 if (res == NULL)
674 out_of_mem();
675 res->ai_flags = hints.ai_flags;
676 res->ai_family = hints.ai_family;
677 res->ai_protocol = hints.ai_protocol;
678 switch (res->ai_family) {
679 case AF_INET:
680 sin = malloc(sizeof(struct sockaddr_in));
681 if (sin == NULL)
682 out_of_mem();
683 sin->sin_family = AF_INET;
684 sin->sin_port = htons(0);
685 sin->sin_addr.s_addr = htonl(INADDR_ANY);
686 res->ai_addr = (struct sockaddr*) sin;
687 res->ai_addrlen = (socklen_t)
688 sizeof(res->ai_addr);
689 break;
690 case AF_INET6:
691 sin6 = malloc(sizeof(struct sockaddr_in6));
692 if (sin6 == NULL)
693 out_of_mem();
694 sin6->sin6_family = AF_INET6;
695 sin6->sin6_port = htons(0);
696 sin6->sin6_addr = in6addr_any;
697 res->ai_addr = (struct sockaddr*) sin6;
698 res->ai_addrlen = (socklen_t) sizeof(res->ai_addr);
699 break;
700 default:
701 break;
702 }
703 } else {
704 if ((aicode = getaddrinfo(NULL, svcport_str,
705 &hints, &res)) != 0) {
706 syslog(LOG_ERR,
707 "cannot get local address for %s: %s",
708 nconf->nc_netid,
709 gai_strerror(aicode));
710 continue;
711 }
712 }
713 } else {
714 if ((aicode = getaddrinfo(hosts[nhostsbak], svcport_str,
715 &hints, &res)) != 0) {
716 syslog(LOG_ERR,
717 "cannot get local address for %s: %s",
718 nconf->nc_netid, gai_strerror(aicode));
719 continue;
720 }
721 }
722
723 servaddr.len = servaddr.maxlen = res->ai_addr->sa_len;
724 servaddr.buf = res->ai_addr;
725 uaddr = taddr2uaddr(nconf, &servaddr);
726
727 addrs = realloc(addrs, 2 * (naddrs + 1) * sizeof(char *));
728 if (!addrs)
729 out_of_mem();
730 addrs[2 * naddrs] = strdup(nconf->nc_netid);
731 addrs[2 * naddrs + 1] = uaddr;
732 naddrs++;
733 } /* end while */
734}
735
736void
503sigalarm_handler(void)
504{
505
506 grace_expired = 1;
507}
508
509void
510usage()
511{
737sigalarm_handler(void)
738{
739
740 grace_expired = 1;
741}
742
743void
744usage()
745{
512 errx(1, "usage: rpc.lockd [-d ]"
746 errx(1, "usage: rpc.lockd [-k] [-d <debuglevel>]"
513 " [-g <grace period>] [-h <bindip>] [-p <port>]");
514}
515
516/*
517 * init_nsm --
518 * Reset the NSM state-of-the-world and acquire its state.
519 */
520void

--- 54 unchanged lines hidden ---
747 " [-g <grace period>] [-h <bindip>] [-p <port>]");
748}
749
750/*
751 * init_nsm --
752 * Reset the NSM state-of-the-world and acquire its state.
753 */
754void

--- 54 unchanged lines hidden ---