Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.sbin/mountd Make address handling in mountd more generic...



details:   https://anonhg.NetBSD.org/src/rev/ceb6be14fd7a
branches:  trunk
changeset: 487525:ceb6be14fd7a
user:      fvdl <fvdl%NetBSD.org@localhost>
date:      Fri Jun 09 00:03:31 2000 +0000

description:
Make address handling in mountd more generic, to allow IPv6 mounting.
Add IPv6 example to exports manpage. Allow /prefix notation for
networks.

diffstat:

 usr.sbin/mountd/exports.5 |   16 +-
 usr.sbin/mountd/mountd.c  |  708 ++++++++++++++++++++++++++++++++-------------
 2 files changed, 515 insertions(+), 209 deletions(-)

diffs (truncated from 1033 to 300 lines):

diff -r ca6fea8e1305 -r ceb6be14fd7a usr.sbin/mountd/exports.5
--- a/usr.sbin/mountd/exports.5 Fri Jun 09 00:00:17 2000 +0000
+++ b/usr.sbin/mountd/exports.5 Fri Jun 09 00:03:31 2000 +0000
@@ -1,4 +1,4 @@
-.\"    $NetBSD: exports.5,v 1.15 2000/02/17 09:05:07 fvdl Exp $
+.\"    $NetBSD: exports.5,v 1.16 2000/06/09 00:03:31 fvdl Exp $
 .\"
 .\" Copyright (c) 1989, 1991, 1993
 .\"    The Regents of the University of California.  All rights reserved.
@@ -262,6 +262,8 @@
 /usr -maproot=daemon grumpy.cis.uoguelph.ca 131.104.48.16
 /usr -ro -mapall=nobody
 /u -maproot=bin: -network 131.104.48 -mask 255.255.255.0
+/a -network 192.168.0/24
+/a -network 3ffe:1ce1:1:fe80::/64
 /u2 -maproot=root friends
 /u2 -alldirs -kerb -network cis-net -mask cis-mask
 .Ed
@@ -301,6 +303,18 @@
 it is exported to all hosts on network ``cis-net'' allowing mounts at any
 directory within /u2 and mapping all uids to credentials for the principal
 that is authenticated by a Kerberos ticket.
+.Pp
+.Sy /a
+is exported to the network 192.168.0.0, with a netmask of 255.255.255.0.
+However, the netmask length in the entry for /a is not specified through
+a -mask option, but through the /prefix notation.
+.Pp
+.Sy /a
+is also exported to the IPv6 network 3ffe:1ce1:1:fe80:: address, using
+the upper 64 bits as the prefix. Note that, unlike with IPv4 network
+addresses, the specified network address must be complete, and not just
+contain the upper bits. With IPv6 addresses, the -mask option must not
+be used.
 .Sh FILES
 .Bl -tag -width /etc/exports -compact
 .It Pa /etc/exports
diff -r ca6fea8e1305 -r ceb6be14fd7a usr.sbin/mountd/mountd.c
--- a/usr.sbin/mountd/mountd.c  Fri Jun 09 00:00:17 2000 +0000
+++ b/usr.sbin/mountd/mountd.c  Fri Jun 09 00:03:31 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: mountd.c,v 1.63 2000/06/03 14:20:49 fvdl Exp $      */
+/*     $NetBSD: mountd.c,v 1.64 2000/06/09 00:03:32 fvdl Exp $  */
 
 /*
  * Copyright (c) 1989, 1993
@@ -51,7 +51,7 @@
 #if 0
 static char     sccsid[] = "@(#)mountd.c  8.15 (Berkeley) 5/1/95";
 #else
-__RCSID("$NetBSD: mountd.c,v 1.63 2000/06/03 14:20:49 fvdl Exp $");
+__RCSID("$NetBSD: mountd.c,v 1.64 2000/06/09 00:03:32 fvdl Exp $");
 #endif
 #endif                         /* not lint */
 
@@ -140,13 +140,13 @@
 #define        EX_LINKED       0x1
 
 struct netmsk {
-       u_int32_t       nt_net;
-       u_int32_t       nt_mask;
+       struct sockaddr_storage nt_net;
+       int             nt_len;
        char           *nt_name;
 };
 
 union grouptypes {
-       struct hostent *gt_hostent;
+       struct addrinfo *gt_addrinfo;
        struct netmsk   gt_net;
 #ifdef ISO
        struct sockaddr_iso *gt_isoaddr;
@@ -183,7 +183,7 @@
 static void add_mlist __P((char *, char *, int));
 static int check_dirpath __P((const char *, size_t, char *));
 static int check_options __P((const char *, size_t, struct dirlist *));
-static int chk_host __P((struct dirlist *, u_int32_t, int *, int *));
+static int chk_host __P((struct dirlist *, struct sockaddr *, int *, int *));
 static int del_mlist __P((char *, char *, struct sockaddr *));
 static struct dirlist *dirp_search __P((struct dirlist *, char *));
 static int do_mount __P((const char *, size_t, struct exportlist *,
@@ -214,7 +214,7 @@
 static void nextfield __P((char **, char **));
 static void parsecred __P((char *, struct ucred *));
 static int put_exlist __P((struct dirlist *, XDR *, struct dirlist *, int *));
-static int scan_tree __P((struct dirlist *, u_int32_t));
+static int scan_tree __P((struct dirlist *, struct sockaddr *));
 static void send_umntall __P((int));
 static int umntall_each __P((caddr_t, struct sockaddr_in *));
 static int xdr_dir __P((XDR *, char *));
@@ -223,6 +223,11 @@
 static int xdr_mlist __P((XDR *, caddr_t));
 static void *emalloc __P((size_t));
 static char *estrdup __P((const char *));
+static int bitcmp __P((void *, void *, int));
+static int netpartcmp __P((struct sockaddr *, struct sockaddr *, int));
+static int sacmp __P((struct sockaddr *, struct sockaddr *));
+static int allones __P((struct sockaddr_storage *, int));
+static int countones __P((struct sockaddr *));
 #ifdef ISO
 static int get_isoaddr __P((const char *, size_t, char *, struct grouplist *));
 #endif
@@ -237,7 +242,9 @@
        0,
        {}
 };
-       static int      opt_flags;
+
+static int      opt_flags;
+
 /* Bits for above */
 #define        OP_MAPROOT      0x001
 #define        OP_MAPALL       0x002
@@ -248,6 +255,7 @@
 #define        OP_ALLDIRS      0x040
 #define OP_NORESPORT   0x080
 #define OP_NORESMNT    0x100
+#define OP_MASKLEN     0x200
 
 static int      debug = 0;
 #if 0
@@ -268,8 +276,11 @@
        int argc;
        char **argv;
 {
-       SVCXPRT *udptransp, *tcptransp;
-       int c;
+       SVCXPRT *udptransp, *tcptransp, *udp6transp, *tcp6transp;
+       struct netconfig *udpconf, *tcpconf, *udp6conf, *tcp6conf;
+       int udpsock, tcpsock, udp6sock, tcp6sock;
+       int xcreated = 0;
+       int c, one = 1;
 
        while ((c = getopt(argc, argv, "dnr")) != -1)
                switch (c) {
@@ -310,24 +321,107 @@
        (void)signal(SIGHUP, get_exportlist);
        (void)signal(SIGTERM, send_umntall);
        pidfile(NULL);
-       if ((udptransp = svcudp_create(RPC_ANYSOCK)) == NULL ||
-           (tcptransp = svctcp_create(RPC_ANYSOCK, 0, 0)) == NULL) {
-               syslog(LOG_ERR, "Can't create socket");
+
+       rpcb_unset(RPCPROG_MNT, RPCMNT_VER1, NULL);
+       rpcb_unset(RPCPROG_MNT, RPCMNT_VER3, NULL);
+
+       udpsock  = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+       tcpsock  = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+       udp6sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
+       tcp6sock = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
+
+       /*
+        * We're doing host-based access checks here, so don't allow
+        * v4-in-v6 to confuse things. The kernel will disable it
+        * by default on NFS sockets too.
+        */
+       if (udp6sock != -1 && setsockopt(udp6sock, IPPROTO_IPV6,
+           IPV6_BINDV6ONLY, &one, sizeof one) < 0){
+               syslog(LOG_ERR, "can't disable v4-in-v6 on UDP socket");
+               exit(1);
+       }
+       if (tcp6sock != -1 && setsockopt(tcp6sock, IPPROTO_IPV6,
+           IPV6_BINDV6ONLY, &one, sizeof one) < 0){
+               syslog(LOG_ERR, "can't disable v4-in-v6 on UDP socket");
                exit(1);
        }
-       pmap_unset(RPCPROG_MNT, RPCMNT_VER1);
-       pmap_unset(RPCPROG_MNT, RPCMNT_VER3);
-       if (!svc_register(udptransp, RPCPROG_MNT, RPCMNT_VER1, mntsrv,
-           IPPROTO_UDP) ||
-           !svc_register(udptransp, RPCPROG_MNT, RPCMNT_VER3, mntsrv,
-           IPPROTO_UDP) ||
-           !svc_register(tcptransp, RPCPROG_MNT, RPCMNT_VER1, mntsrv,
-           IPPROTO_TCP) ||
-           !svc_register(tcptransp, RPCPROG_MNT, RPCMNT_VER3, mntsrv,
-           IPPROTO_TCP)) {
-               syslog(LOG_ERR, "Can't register mount");
+
+       udpconf  = getnetconfigent("udp");
+       tcpconf  = getnetconfigent("tcp");
+       udp6conf = getnetconfigent("udp6");
+       tcp6conf = getnetconfigent("tcp6");
+
+       if (udpsock != -1 && udpconf != NULL) {
+               bindresvport(udpsock, NULL);
+               udptransp = svc_dg_create(udpsock, 0, 0);
+               if (udptransp != NULL) {
+                       if (!svc_reg(udptransp, RPCPROG_MNT, RPCMNT_VER1,
+                               mntsrv, udpconf) ||
+                           !svc_reg(udptransp, RPCPROG_MNT, RPCMNT_VER3,
+                               mntsrv, udpconf))
+                               syslog(LOG_WARNING, "can't register UDP service");
+                       else
+                               xcreated++;
+               } else
+                       syslog(LOG_WARNING, "can't create UDP service");
+                       
+       }
+
+       if (tcpsock != -1 && tcpconf != NULL) {
+               bindresvport(tcpsock, NULL);
+               listen(tcpsock, SOMAXCONN);
+               tcptransp = svc_vc_create(tcpsock, 0, 0);
+               if (tcptransp != NULL) {
+                       if (!svc_reg(tcptransp, RPCPROG_MNT, RPCMNT_VER1,
+                               mntsrv, tcpconf) ||
+                           !svc_reg(udptransp, RPCPROG_MNT, RPCMNT_VER3,
+                               mntsrv, tcpconf))
+                               syslog(LOG_WARNING, "can't register TCP service");
+                       else
+                               xcreated++;
+               } else
+                       syslog(LOG_WARNING, "can't create TCP service");
+                       
+       }
+
+       if (udp6sock != -1 && udp6conf != NULL) {
+               bindresvport(udp6sock, NULL);
+               udp6transp = svc_dg_create(udp6sock, 0, 0);
+               if (udp6transp != NULL) {
+                       if (!svc_reg(udp6transp, RPCPROG_MNT, RPCMNT_VER1,
+                               mntsrv, udp6conf) ||
+                           !svc_reg(udp6transp, RPCPROG_MNT, RPCMNT_VER3,
+                               mntsrv, udp6conf))
+                               syslog(LOG_WARNING, "can't register UDP6 service");
+                       else
+                               xcreated++;
+               } else
+                       syslog(LOG_WARNING, "can't create UDP6 service");
+                       
+       }
+
+       if (tcp6sock != -1 && tcp6conf != NULL) {
+               bindresvport(tcp6sock, NULL);
+               listen(tcpsock, SOMAXCONN);
+               tcp6transp = svc_vc_create(tcp6sock, 0, 0);
+               if (tcp6transp != NULL) {
+                       if (!svc_reg(tcp6transp, RPCPROG_MNT, RPCMNT_VER1,
+                               mntsrv, tcp6conf) ||
+                           !svc_reg(tcp6transp, RPCPROG_MNT, RPCMNT_VER3,
+                               mntsrv, tcp6conf))
+                               syslog(LOG_WARNING, "can't register TCP6 service");
+                       else
+                               xcreated++;
+               } else
+                       syslog(LOG_WARNING, "can't create TCP6 service");
+                       
+       }
+
+       if (xcreated == 0) {
+               syslog(LOG_ERR, "could not create any services");
                exit(1);
        }
+
 #ifdef KERBEROS
        kuidinit();
 #endif
@@ -349,19 +443,39 @@
        struct fhreturn fhr;
        struct stat     stb;
        struct statfs   fsb;
-       struct hostent *hp;
-       struct in_addr  saddr;
+       struct addrinfo *ai;
+       char host[NI_MAXHOST], numerichost[NI_MAXHOST];
+       int lookup_failed = 1;
+       struct sockaddr *saddr;
        u_short         sport;
        char            rpcpath[RPCMNT_PATHLEN + 1], dirpath[MAXPATHLEN];
        long            bad = EACCES;
        int             defset, hostset, ret;
        sigset_t        sighup_mask;
+       struct sockaddr_in6 *sin6;
+       struct sockaddr_in *sin;
 
        (void)sigemptyset(&sighup_mask);
        (void)sigaddset(&sighup_mask, SIGHUP);
-       saddr = transp->xp_raddr.sin_addr;
-       sport = ntohs(transp->xp_raddr.sin_port);
-       hp = NULL;
+       saddr = svc_getrpccaller(transp)->buf;
+       switch (saddr->sa_family) {
+       case AF_INET6:
+               sin6 = (struct sockaddr_in6 *)saddr;
+               sport = ntohs(sin6->sin6_port);
+               break;
+       case AF_INET:
+               sin = (struct sockaddr_in *)saddr;
+               sport = ntohs(sin->sin_port);
+               break;
+       default:
+               syslog(LOG_ERR, "request from unknown address family");
+               return;
+       }
+       lookup_failed = getnameinfo(saddr, saddr->sa_len, host, sizeof host, 
+           NULL, 0, 0);
+       getnameinfo(saddr, saddr->sa_len, numerichost,
+           sizeof numerichost, NULL, 0, NI_NUMERICHOST);
+       ai = NULL;
 #ifdef KERBEROS



Home | Main Index | Thread Index | Old Index