diff options
Diffstat (limited to 'usr.sbin/rpc.lockd/lockd.c')
-rw-r--r-- | usr.sbin/rpc.lockd/lockd.c | 231 |
1 files changed, 175 insertions, 56 deletions
diff --git a/usr.sbin/rpc.lockd/lockd.c b/usr.sbin/rpc.lockd/lockd.c index ac32856..e0ac5cf 100644 --- a/usr.sbin/rpc.lockd/lockd.c +++ b/usr.sbin/rpc.lockd/lockd.c @@ -1,3 +1,6 @@ +/* $NetBSD: lockd.c,v 1.7 2000/08/12 18:08:44 thorpej Exp $ */ +/* $FreeBSD$ */ + /* * Copyright (c) 1995 * A.R. Gordon (andrew.gordon@net-tel.co.uk). All rights reserved. @@ -31,77 +34,193 @@ * */ +#include <sys/cdefs.h> #ifndef lint -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ +__RCSID("$NetBSD: lockd.c,v 1.7 2000/08/12 18:08:44 thorpej Exp $"); +#endif + +/* + * main() function for NFS lock daemon. Most of the code in this + * file was generated by running rpcgen /usr/include/rpcsvc/nlm_prot.x. + * + * The actual program logic is in the file lock_proc.c + */ -/* main() function for NFS lock daemon. Most of the code in this */ -/* file was generated by running rpcgen /usr/include/rpcsvc/nlm_prot.x */ -/* The actual program logic is in the file procs.c */ +#include <sys/types.h> +#include <sys/socket.h> #include <err.h> +#include <stdio.h> #include <stdlib.h> +#include <errno.h> +#include <syslog.h> +#include <signal.h> #include <string.h> +#include <unistd.h> +#include <libutil.h> +#include <netconfig.h> + #include <rpc/rpc.h> -#include <rpc/pmap_clnt.h> +#include <rpcsvc/sm_inter.h> + #include "lockd.h" +#include <rpcsvc/nlm_prot.h> + +int debug_level = 0; /* 0 = no debugging syslog() calls */ +int _rpcsvcdirty = 0; + +int grace_expired; -void nlm_prog_1 __P((struct svc_req *, SVCXPRT *)); -void nlm_prog_3 __P((struct svc_req *, SVCXPRT *)); -static void usage __P((void)); +int main __P((int, char **)); +void nlm_prog_0 __P((struct svc_req *, SVCXPRT *)); +void nlm_prog_1 __P((struct svc_req *, SVCXPRT *)); +void nlm_prog_3 __P((struct svc_req *, SVCXPRT *)); +void nlm_prog_4 __P((struct svc_req *, SVCXPRT *)); +void usage __P((void)); -int debug_level = 0; /* Zero means no debugging syslog() calls */ +void sigalarm_handler __P((int)); + +char *transports[] = { "udp", "tcp", "udp6", "tcp6" }; int -main(int argc, char **argv) +main(argc, argv) + int argc; + char **argv; +{ + SVCXPRT *transp; + int ch, i, maxindex, s; + struct sigaction sigchild, sigalarm; + int grace_period = 30; + struct netconfig *nconf; + + while ((ch = getopt(argc, argv, "d:g:")) != (-1)) { + switch (ch) { + case 'd': + debug_level = atoi(optarg); + if (!debug_level) { + usage(); + /* NOTREACHED */ + } + break; + case 'g': + grace_period = atoi(optarg); + if (!grace_period) { + usage(); + /* NOTREACHED */ + } + break; + default: + case '?': + usage(); + /* NOTREACHED */ + } + } + if (geteuid()) { /* This command allowed only to root */ + fprintf(stderr, "Sorry. You are not superuser\n"); + exit(1); + } + + (void)rpcb_unset(NLM_PROG, NLM_SM, NULL); + (void)rpcb_unset(NLM_PROG, NLM_VERS, NULL); + (void)rpcb_unset(NLM_PROG, NLM_VERSX, NULL); + (void)rpcb_unset(NLM_PROG, NLM_VERS4, NULL); + + /* + * Check if IPv6 support is present. + */ + s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); + if (s < 0) + maxindex = 2; + else { + close(s); + maxindex = 4; + } + + for (i = 0; i < maxindex; i++) { + nconf = getnetconfigent(transports[i]); + if (nconf == NULL) + errx(1, "cannot get udp netconf."); + + transp = svc_tli_create(RPC_ANYFD, nconf, NULL, 0, 0); + if (transp == NULL) { + errx(1, "cannot create %s service.", transports[i]); + /* NOTREACHED */ + } + if (!svc_reg(transp, NLM_PROG, NLM_SM, nlm_prog_0, nconf)) { + errx(1, "unable to register (NLM_PROG, NLM_SM, %s)", + transports[i]); + /* NOTREACHED */ + } + if (!svc_reg(transp, NLM_PROG, NLM_VERS, nlm_prog_1, nconf)) { + errx(1, "unable to register (NLM_PROG, NLM_VERS, %s)", + transports[i]); + /* NOTREACHED */ + } + if (!svc_reg(transp, NLM_PROG, NLM_VERSX, nlm_prog_3, nconf)) { + errx(1, "unable to register (NLM_PROG, NLM_VERSX, %s)", + transports[i]); + /* NOTREACHED */ + } + if (!svc_reg(transp, NLM_PROG, NLM_VERS4, nlm_prog_4, nconf)) { + errx(1, "unable to register (NLM_PROG, NLM_VERS4, %s)", + transports[i]); + /* NOTREACHED */ + } + freenetconfigent(nconf); + } + + /* + * Note that it is NOT sensible to run this program from inetd - the + * protocol assumes that it will run immediately at boot time. + */ + if (daemon(0, 0)) { + err(1, "cannot fork"); + /* NOTREACHED */ + } + + openlog("rpc.lockd", 0, LOG_DAEMON); + if (debug_level) + syslog(LOG_INFO, "Starting, debug level %d", debug_level); + else + syslog(LOG_INFO, "Starting"); + + sigchild.sa_handler = sigchild_handler; + sigemptyset(&sigchild.sa_mask); + sigchild.sa_flags = SA_RESTART; + if (sigaction(SIGCHLD, &sigchild, NULL) != 0) { + syslog(LOG_WARNING, "sigaction(SIGCHLD) failed: %s", + strerror(errno)); + exit(1); + } + sigalarm.sa_handler = sigalarm_handler; + sigemptyset(&sigalarm.sa_mask); + sigalarm.sa_flags = SA_RESETHAND; /* should only happen once */ + sigalarm.sa_flags |= SA_RESTART; + if (sigaction(SIGALRM, &sigalarm, NULL) != 0) { + syslog(LOG_WARNING, "sigaction(SIGALRM) failed: %s", + strerror(errno)); + exit(1); + } + grace_expired = 0; + if (alarm(10) < 0) { + syslog(LOG_WARNING, "alarm failed: %s", + strerror(errno)); + exit(1); + } + + svc_run(); /* Should never return */ + exit(1); +} + +void +sigalarm_handler(s) + int s; { - SVCXPRT *transp; - - if (argc > 1) - { - if (strncmp(argv[1], "-d", 2)) - usage(); - if (argc > 2) debug_level = atoi(argv[2]); - else debug_level = atoi(argv[1] + 2); - /* Ensure at least some debug if -d with no specified level */ - if (!debug_level) debug_level = 1; - } - - (void)pmap_unset(NLM_PROG, NLM_VERS); - (void)pmap_unset(NLM_PROG, NLM_VERSX); - - transp = svcudp_create(RPC_ANYSOCK); - if (transp == NULL) - errx(1, "cannot create udp service"); - if (!svc_register(transp, NLM_PROG, NLM_VERS, nlm_prog_1, IPPROTO_UDP)) - errx(1, "unable to register (NLM_PROG, NLM_VERS, udp)"); - if (!svc_register(transp, NLM_PROG, NLM_VERSX, nlm_prog_3, IPPROTO_UDP)) - errx(1, "unable to register (NLM_PROG, NLM_VERSX, udp)"); - - transp = svctcp_create(RPC_ANYSOCK, 0, 0); - if (transp == NULL) - errx(1, "cannot create tcp service"); - if (!svc_register(transp, NLM_PROG, NLM_VERS, nlm_prog_1, IPPROTO_TCP)) - errx(1, "unable to register (NLM_PROG, NLM_VERS, tcp)"); - if (!svc_register(transp, NLM_PROG, NLM_VERSX, nlm_prog_3, IPPROTO_TCP)) - errx(1, "unable to register (NLM_PROG, NLM_VERSX, tcp)"); - - /* Note that it is NOT sensible to run this program from inetd - the */ - /* protocol assumes that it will run immediately at boot time. */ - if (daemon(0,0)) - err(1, "fork"); - openlog("rpc.lockd", 0, LOG_DAEMON); - if (debug_level) syslog(LOG_INFO, "Starting, debug level %d", debug_level); - else syslog(LOG_INFO, "Starting"); - - svc_run(); /* Should never return */ - exit(1); + grace_expired = 1; } -static void +void usage() { - fprintf(stderr, "usage: rpc.lockd [-d [debuglevel]]\n"); - exit(1); + errx(1, "usage: rpc.lockd [-d <debuglevel>] [-g <grace period>]"); } |