diff --git a/usr.sbin/rpc.lockd/lockd.c b/usr.sbin/rpc.lockd/lockd.c index 20fec254d859..15c9d69fb9ee 100644 --- a/usr.sbin/rpc.lockd/lockd.c +++ b/usr.sbin/rpc.lockd/lockd.c @@ -92,13 +92,17 @@ main(argc, argv) char **argv; { SVCXPRT *transp; - int ch, i, maxindex, s; + int ch, i, maxindex, r, s, sock; + struct sockaddr_in sin; + struct sockaddr_in6 sin6; + char *endptr; struct sigaction sigalarm; int grace_period = 30; struct netconfig *nconf; int maxrec = RPC_MAXDATASIZE; + in_port_t svcport = 0; - while ((ch = getopt(argc, argv, "d:g:")) != (-1)) { + while ((ch = getopt(argc, argv, "d:g:p:")) != (-1)) { switch (ch) { case 'd': debug_level = atoi(optarg); @@ -114,6 +118,13 @@ main(argc, argv) /* NOTREACHED */ } break; + case 'p': + endptr = NULL; + svcport = (in_port_t)strtoul(optarg, &endptr, 10); + if (endptr == NULL || *endptr != '\0' || + svcport == 0 || svcport >= IPPORT_MAX) + usage(); + break; default: case '?': usage(); @@ -141,16 +152,81 @@ main(argc, argv) maxindex = 4; } + if (svcport != 0) { + bzero(&sin, sizeof(struct sockaddr_in)); + sin.sin_len = sizeof(struct sockaddr_in); + sin.sin_family = AF_INET; + sin.sin_port = htons(svcport); + + bzero(&sin6, sizeof(struct sockaddr_in6)); + sin6.sin6_len = sizeof(struct sockaddr_in6); + sin6.sin6_family = AF_INET6; + sin6.sin6_port = htons(svcport); + } + rpc_control(RPC_SVC_CONNMAXREC_SET, &maxrec); for (i = 0; i < maxindex; i++) { nconf = getnetconfigent(transports[i]); if (nconf == NULL) - errx(1, "cannot get %s netconf: %s.", transports[i], - nc_sperror()); + errx(1, "cannot get %s netconf: %s.", transports[i], + nc_sperror()); + + if (svcport != 0) { + if (strcmp(nconf->nc_netid, "udp6") == 0) { + sock = socket(AF_INET6, SOCK_DGRAM, + IPPROTO_UDP); + if (sock != -1) { + r = bindresvport_sa(sock, + (struct sockaddr *)&sin6); + if (r != 0) { + syslog(LOG_ERR, "bindresvport: %m"); + exit(1); + } + } + } + else if (strcmp(nconf->nc_netid, "udp") == 0) { + sock = socket(AF_INET, SOCK_DGRAM, + IPPROTO_UDP); + if (sock != -1) { + r = bindresvport(sock, &sin); + if (r != 0) { + syslog(LOG_ERR, "bindresvport: %m"); + exit(1); + } + } + } + else if (strcmp(nconf->nc_netid, "tcp6") == 0) { + sock = socket(AF_INET6, SOCK_STREAM, + IPPROTO_TCP); + if (sock != -1) { + r = bindresvport_sa(sock, + (struct sockaddr *)&sin6); + if (r != 0) { + syslog(LOG_ERR, "bindresvport: %m"); + exit(1); + } + } + } + else if (strcmp(nconf->nc_netid, "tcp") == 0) { + sock = socket(AF_INET, SOCK_STREAM, + IPPROTO_TCP); + if (sock != -1) { + r = bindresvport(sock, &sin); + if (r != 0) { + syslog(LOG_ERR, "bindresvport: %m"); + exit(1); + } + } + } + + transp = svc_tli_create(sock, nconf, NULL, + RPC_MAXDATASIZE, RPC_MAXDATASIZE); + } else { + transp = svc_tli_create(RPC_ANYFD, nconf, NULL, + RPC_MAXDATASIZE, RPC_MAXDATASIZE); + } - transp = svc_tli_create(RPC_ANYFD, nconf, NULL, - RPC_MAXDATASIZE, RPC_MAXDATASIZE); if (transp == NULL) { errx(1, "cannot create %s service.", transports[i]); /* NOTREACHED */ @@ -223,7 +299,8 @@ sigalarm_handler(void) void usage() { - errx(1, "usage: rpc.lockd [-d ] [-g ]"); + errx(1, "usage: rpc.lockd [-d ]" + " [-g ] [-p ]"); } /* diff --git a/usr.sbin/rpc.lockd/rpc.lockd.8 b/usr.sbin/rpc.lockd/rpc.lockd.8 index 7c86bb6775cd..0b5d3486e673 100644 --- a/usr.sbin/rpc.lockd/rpc.lockd.8 +++ b/usr.sbin/rpc.lockd/rpc.lockd.8 @@ -33,7 +33,7 @@ .\" .\" $FreeBSD$ .\" -.Dd September 24, 1995 +.Dd April 3, 2007 .Dt RPC.LOCKD 8 .Os .Sh NAME @@ -43,6 +43,7 @@ .Nm .Op Fl d Ar debug_level .Op Fl g Ar grace period +.Op Fl p Ar port .Sh DESCRIPTION The .Nm @@ -83,6 +84,12 @@ During the grace period only accepts requests from hosts which are reinitialising locks which existed before the server restart. Default is 30 seconds. +.It Fl p +The +.Fl p +option allow to force the daemon to bind to the specified +.Ar port , +for both AF_INET and AF_INET6 address families. .El .Pp Error conditions are logged to syslog, irrespective of the debug level,