Index: include/rpc/svc.h =================================================================== RCS file: /cvs/openbsd/src/include/rpc/svc.h,v retrieving revision 1.9 diff -u -u -r1.9 svc.h --- include/rpc/svc.h 22 Jan 2004 21:48:02 -0000 1.9 +++ include/rpc/svc.h 12 Jun 2007 07:06:33 -0000 @@ -305,6 +305,9 @@ __BEGIN_DECLS extern SVCXPRT *svcudp_create(int); extern SVCXPRT *svcudp_bufcreate(int, unsigned int, unsigned int); +extern SVCXPRT *svcudp_create2(int, int, u_short); +extern SVCXPRT *svcudp_bufcreate2(int, int, u_short, unsigned int, + unsigned int); __END_DECLS @@ -313,6 +316,7 @@ */ __BEGIN_DECLS extern SVCXPRT *svctcp_create(int, unsigned int, unsigned int); +extern SVCXPRT *svctcp_create2(int, int, u_short, unsigned int, unsigned int); __END_DECLS /* Index: lib/libc/rpc/rpc.3 =================================================================== RCS file: /cvs/openbsd/src/lib/libc/rpc/rpc.3,v retrieving revision 1.38 diff -u -u -r1.38 rpc.3 --- lib/libc/rpc/rpc.3 31 May 2007 19:19:30 -0000 1.38 +++ lib/libc/rpc/rpc.3 12 Jun 2007 07:06:36 -0000 @@ -78,7 +78,7 @@ .\" 2550 Garcia Avenue .\" Mountain View, California 94043 .\" -.Dd $Mdocdate$ +.Dd $Mdocdate: May 31 2007 $ .Dt RPC 3 .Os .Sh NAME @@ -134,7 +134,11 @@ .Nm svcerr_weakauth , .Nm svcfd_create , .Nm svctcp_create , +.Nm svctcp_create2 , .Nm svcudp_bufcreate , +.Nm svcudp_bufcreate2 , +.Nm svcudp_create , +.Nm svcudp_create2 , .Nm xdr_accepted_reply , .Nm xdr_authunix_parms , .Nm xdr_callhdr , @@ -259,9 +263,17 @@ .Ft SVCXPRT * .Fn svctcp_create "int sock" "u_int send_buf_size" "u_int recv_buf_size" .Ft SVCXPRT * +.Fn svctcp_create2 "int sock" "int family" "u_short port" "u_int send_buf_size" "u_int recv_buf_size" +.Ft SVCXPRT * .Fn svcfd_create "int fd" "u_int sendsize" "u_int recvsize" .Ft SVCXPRT * -.Fn svcudp_bufcreate "int sock" +.Fn svcudp_bufcreate "int sock" "u_int send_buf_size" "u_int recv_buf_size" +.Ft SVCXPRT * +.Fn svcudp_bufcreate2 "int sock" "int family" "u_short port" "u_int send_buf_size" "u_int recv_buf_size" +.Ft SVCXPRT * +.Fn svcudp_create "int sock" +.Ft SVCXPRT * +.Fn svcudp_create2 "int sock" "int family" "u_short port" .Ft bool_t .Fn xdr_accepted_reply "XDR *xdrs" "struct accepted_reply *ar" .Ft bool_t @@ -1227,6 +1239,13 @@ users may specify the size of buffers; values of zero choose suitable defaults. .Pp +.Fn svctcp_create2 +supersedes +.Fn svctcp_create +function. It allows to specify address family and port number also. This +function accepts AF_INET and AF_INET6 address families. If port is equal to 0, +the function tries to bind socket to one of reserved ports. +.Pp .Fn svcfd_create will create a service on top of any open descriptor. Typically, this descriptor is a connected socket for a stream protocol such @@ -1265,6 +1284,13 @@ .Tn UDP-based .Tn RPC messages. +.Pp +.Fn svcudp_bufcreate2 +supersedes +.Fn svcudp_bufcreate +function. It allows to specify address family and port number also. This +function accepts AF_INET and AF_INET6 address families. If port is equal to 0, +the function tries to bind socket to one of reserved ports. .Pp .Fn xdr_accepted_reply is used for encoding Index: lib/libc/rpc/svc_tcp.c =================================================================== RCS file: /cvs/openbsd/src/lib/libc/rpc/svc_tcp.c,v retrieving revision 1.28 diff -u -u -r1.28 svc_tcp.c --- lib/libc/rpc/svc_tcp.c 2 Apr 2006 00:36:05 -0000 1.28 +++ lib/libc/rpc/svc_tcp.c 12 Jun 2007 07:06:36 -0000 @@ -135,7 +135,7 @@ if (sock == RPC_ANYSOCK) { if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { - perror("svctcp_.c - udp socket creation problem"); + perror("svctcp_.c - tcp socket creation problem"); return (NULL); } madesock = TRUE; @@ -185,6 +185,119 @@ return (NULL); } return (xprt); +} + +/* + * This function creates sock (with specified adress family) if sock is -1. + * Then binds it to the specified port. It's possible to create v4 and v6 + * sockets. + */ +SVCXPRT * +svctcp_create2(int sock, int af, u_short port, u_int sendsize, u_int recvsize) +{ + struct tcp_rendezvous *r; + SVCXPRT *xprt; + struct sockaddr *sa; + struct sockaddr_in sin; +#ifdef INET6 + struct sockaddr_in6 sin6; +#endif + socklen_t salen; + bool_t madesock; + int error; + +#ifdef INET6 + if (af != AF_INET && af != AF_INET6) + return (NULL); +#else + if (af != AF_INET) + return (NULL); +#endif + + madesock = FALSE; + + if (sock == RPC_ANYSOCK) { + sock = socket(af, SOCK_STREAM, 0); + if (sock == -1) + return (NULL); + madesock = TRUE; + } + + if (af == AF_INET) { + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_port = htons(port); + sin.sin_addr.s_addr = INADDR_ANY; + salen = sizeof(sin); + sa = (struct sockaddr *)&sin; + } +#ifdef INET6 + else { + memset(&sin6, 0, sizeof(sin6)); + sin6.sin_family = AF_INET6; + sin6.sin_port = htons(port); + sin6.sin_addr.s_addr = in6addr_any; + salen = sizeof(sin6); + sa = (struct sockaddr *)&sin6; + } +#endif /* INET6 */ + + switch (port) { + case 0: + error = bindresvport_sa(sock, sa); + if (error == 0) + break; + /* FALLTHOUGH */ + default: + error = bind(sock, sa, salen); + break; + } + + if (error != 0 || listen(sock, 2) != 0) { + if (madesock) + close(sock); + return (NULL); + } + + if (port == 0) { + if (getsockname(sock, sa, &salen) != 0) { + if (madesock) + close(sock); + return (NULL); + } + if (af == AF_INET) + port = ntohs(((struct sockaddr_in *)sa)->sin_port); +#ifdef INET6 + else + port = ntohs(((struct sockaddr_in6 *)sa)->sin_port); +#endif + } + + r = (struct tcp_rendezvous *)mem_alloc(sizeof(*r)); + if (r != NULL) { + r->sendsize = sendsize; + r->recvsize = recvsize; + + xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT)); + if (xprt != NULL) { + xprt->xp_p2 = NULL; + xprt->xp_p1 = (caddr_t)r; + xprt->xp_verf = _null_auth; + xprt->xp_ops = &svctcp_rendezvous_op; + xprt->xp_port = port; + xprt->xp_sock = sock; + if (__xprt_register(xprt) != 0) + return (xprt); + + free(xprt); + } + free(r); + } + + if (madesock) + close(sock); + + return (NULL); } /* Index: lib/libc/rpc/svc_udp.c =================================================================== RCS file: /cvs/openbsd/src/lib/libc/rpc/svc_udp.c,v retrieving revision 1.16 diff -u -u -r1.16 svc_udp.c --- lib/libc/rpc/svc_udp.c 8 Aug 2005 08:05:35 -0000 1.16 +++ lib/libc/rpc/svc_udp.c 12 Jun 2007 07:06:36 -0000 @@ -171,6 +171,125 @@ return(svcudp_bufcreate(sock, UDPMSGSIZE, UDPMSGSIZE)); } +SVCXPRT * +svcudp_bufcreate2(int sock, int af, u_short port, u_int sendsz, u_int recvsz) +{ + SVCXPRT *xprt; + struct svcudp_data *su; + struct sockaddr *sa; + struct sockaddr_in sin; +#ifdef INET6 + struct sockaddr_in6 sin6; +#endif + socklen_t salen; + bool_t madesock; + int error; + +#ifdef INET6 + if (af != AF_INET && af != AF_INET6) + return (NULL); +#else + if (af != AF_INET) + return (NULL); +#endif + + madesock = FALSE; + + if (sock == RPC_ANYSOCK) { + sock = socket(af, SOCK_DGRAM, 0); + if (sock == -1) + return (NULL); + madesock = TRUE; + } + + if (af == AF_INET) { + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_port = htons(port); + sin.sin_addr.s_addr = INADDR_ANY; + salen = sizeof(sin); + sa = (struct sockaddr *)&sin; + } +#ifdef INET6 + else { + memset(&sin6, 0, sizeof(sin6)); + sin6.sin_family = AF_INET6; + sin6.sin_port = htons(port); + sin6.sin_addr.s_addr = in6addr_any; + salen = sizeof(sin6); + sa = (struct sockaddr *)&sin6; + } +#endif /* INET6 */ + + switch (port) { + case 0: + error = bindresvport_sa(sock, sa); + if (error == 0) + break; + /* FALLTHOUGH */ + default: + error = bind(sock, sa, salen); + break; + } + + if (error != 0) { + if (madesock) + close(sock); + return (NULL); + } + + if (port == 0) { + if (getsockname(sock, sa, &salen) != 0) { + if (madesock) + close(sock); + return (NULL); + } + if (af == AF_INET) + port = ntohs(((struct sockaddr_in *)sa)->sin_port); +#ifdef INET6 + else + port = ntohs(((struct sockaddr_in6 *)sa)->sin_port); +#endif + } + + xprt = (SVCXPRT *)mem_alloc(sizeof(*xprt)); + if (xprt != NULL) { + su = (struct svcudp_data *)mem_alloc(sizeof(*su)); + if (su != NULL) { + su->su_iosz = ((MAX(sendsz, recvsz) + 3) / 4) * 4; + rpc_buffer(xprt) = mem_alloc(su->su_iosz); + if (rpc_buffer(xprt) != NULL) { + xdrmem_create(&(su->su_xdrs), rpc_buffer(xprt), + su->su_iosz, XDR_DECODE); + su->su_cache = NULL; + xprt->xp_p2 = (caddr_t)su; + xprt->xp_verf.oa_base = su->su_verfbody; + xprt->xp_ops = &svcudp_op; + xprt->xp_port = port; + xprt->xp_sock = sock; + + if (__xprt_register(xprt) != 0) + return (xprt); + + free(rpc_buffer(xprt)); + } + free(su); + } + free(xprt); + } + + if (madesock) + close(sock); + return (NULL); +} + +SVCXPRT * +svcudp_create2(int sock, int af, u_short port) +{ + + return(svcudp_bufcreate2(sock, af, port, UDPMSGSIZE, UDPMSGSIZE)); +} + /* ARGSUSED */ static enum xprt_stat svcudp_stat(SVCXPRT *xprt) Index: sbin/mountd/mountd.8 =================================================================== RCS file: /cvs/openbsd/src/sbin/mountd/mountd.8,v retrieving revision 1.16 diff -u -u -r1.16 mountd.8 --- sbin/mountd/mountd.8 31 May 2007 19:19:46 -0000 1.16 +++ sbin/mountd/mountd.8 12 Jun 2007 07:06:44 -0000 @@ -30,7 +30,7 @@ .\" .\" @(#)mountd.8 8.4 (Berkeley) 4/28/95 .\" -.Dd $Mdocdate$ +.Dd $Mdocdate: May 31 2007 $ .Dt MOUNTD 8 .Os .Sh NAME @@ -41,6 +41,7 @@ .Sh SYNOPSIS .Nm mountd .Op Fl dn +.Op Fl p Ar portnum .Op Ar exportsfile .Sh DESCRIPTION .Nm @@ -71,6 +72,10 @@ The use of .Fl n is STRONGLY discouraged, as it opens up a wide range of security problems. +.It Fl p Ar portnum +Specify port number +.Nm +will listen on. It allows to configure firewall to filter on this port. .It Ar exportsfile The .Ar exportsfile Index: sbin/mountd/mountd.c =================================================================== RCS file: /cvs/openbsd/src/sbin/mountd/mountd.c,v retrieving revision 1.68 diff -u -u -r1.68 mountd.c --- sbin/mountd/mountd.c 1 Jun 2007 05:37:14 -0000 1.68 +++ sbin/mountd/mountd.c 12 Jun 2007 07:06:45 -0000 @@ -65,6 +65,7 @@ #include #include +#include #include #include #include @@ -189,6 +190,8 @@ int xdr_mlist(XDR *, caddr_t); void mountd_svc_run(void); +SVCXPRT * create_svctcp(u_short port, int af); + struct exportlist *exphead; struct mountlist *mlhead; struct grouplist *grphead; @@ -210,6 +213,7 @@ #define OP_ALLDIRS 0x40 int debug = 0; +u_short use_port = 0; /* default: any */ volatile sig_atomic_t gothup; volatile sig_atomic_t gotterm; @@ -228,8 +232,11 @@ SVCXPRT *udptransp, *tcptransp; FILE *pidfile; int c; + char *errstr; + long long portnum; - while ((c = getopt(argc, argv, "dnr")) != -1) + portnum = 0; /* any port */ + while ((c = getopt(argc, argv, "dnrp:")) != -1) switch (c) { case 'd': debug = 1; @@ -240,8 +247,15 @@ case 'r': /* Compatibility */ break; + case 'p': + portnum = strtonum(optarg, 0, USHRT_MAX, &errstr); + if (errstr != NULL) + errx(1, "Port number is invalid"); + use_port = portnum; + break; default: - fprintf(stderr, "Usage: mountd [-dn] [export_file]\n"); + fprintf(stderr, + "Usage: mountd [-dn] [-p port] [export_file]\n"); exit(1); } argc -= optind; @@ -287,8 +301,8 @@ signal(SIGHUP, (void (*)(int)) new_exportlist); signal(SIGTERM, (void (*)(int)) send_umntall); signal(SIGSYS, SIG_IGN); - if ((udptransp = svcudp_create(RPC_ANYSOCK)) == NULL || - (tcptransp = svctcp_create(RPC_ANYSOCK, 0, 0)) == NULL) { + if ((udptransp = svcudp_create2(RPC_ANYSOCK, AF_INET, portnum)) == NULL || + (tcptransp = svctcp_create2(RPC_ANYSOCK, AF_INET, portnum, 0, 0)) == NULL) { syslog(LOG_ERR, "Can't create socket"); exit(1); }