The change ensures that symbolic links are not used in export paths,
authorKeith Bostic <bostic@ucbvax.Berkeley.EDU>
Sat, 29 Jan 1994 09:18:01 +0000 (01:18 -0800)
committerKeith Bostic <bostic@ucbvax.Berkeley.EDU>
Sat, 29 Jan 1994 09:18:01 +0000 (01:18 -0800)
since the match can never succeed after realpath() converts incoming
paths to the "real" one.
From Rick Macklem root@snowhite.cis.uoguelph.ca (Charlie Root)

SCCS-vsn: sbin/mountd/exports.5 8.2
SCCS-vsn: sbin/mountd/mountd.c 8.6

usr/src/sbin/mountd/exports.5
usr/src/sbin/mountd/mountd.c

index 60d556e..aeb1cb1 100644 (file)
@@ -3,7 +3,7 @@
 .\"
 .\" %sccs.include.redist.roff%
 .\"
 .\"
 .\" %sccs.include.redist.roff%
 .\"
-.\"     @(#)exports.5  8.1 (Berkeley) %G%
+.\"     @(#)exports.5  8.2 (Berkeley) %G%
 .\"
 .Dd 
 .Dt EXPORTS 5
 .\"
 .Dd 
 .Dt EXPORTS 5
@@ -46,6 +46,8 @@ followed by the
 .Fl alldirs
 flag;
 this form allows the host(s) to mount any directory within the filesystem.
 .Fl alldirs
 flag;
 this form allows the host(s) to mount any directory within the filesystem.
+The pathnames must not have any symbolic links in them and should not have
+any "." or ".." components.
 Mount points for a filesystem may appear on multiple lines each with
 different sets of hosts and export options.
 .Pp
 Mount points for a filesystem may appear on multiple lines each with
 different sets of hosts and export options.
 .Pp
index d5d4c1d..e871fb0 100644 (file)
@@ -15,7 +15,7 @@ static char copyright[] =
 #endif not lint
 
 #ifndef lint
 #endif not lint
 
 #ifndef lint
-static char sccsid[] = "@(#)mountd.c   8.5 (Berkeley) %G%";
+static char sccsid[] = "@(#)mountd.c   8.6 (Berkeley) %G%";
 #endif not lint
 
 #include <sys/param.h>
 #endif not lint
 
 #include <sys/param.h>
@@ -112,6 +112,7 @@ struct hostlist {
 
 /* Global defs */
 int mntsrv(), umntall_each(), xdr_fhs(), xdr_mlist(), xdr_dir(), xdr_explist();
 
 /* Global defs */
 int mntsrv(), umntall_each(), xdr_fhs(), xdr_mlist(), xdr_dir(), xdr_explist();
+int check_dirpath();
 void get_exportlist(), send_umntall(), nextfield(), out_of_mem();
 void get_mountlist(), add_mlist(), del_mlist(), free_exp(), free_grp();
 void getexp_err(), hang_dirp(), add_dlist(), free_dir(), free_host();
 void get_exportlist(), send_umntall(), nextfield(), out_of_mem();
 void get_mountlist(), add_mlist(), del_mlist(), free_exp(), free_grp();
 void getexp_err(), hang_dirp(), add_dlist(), free_dir(), free_host();
@@ -533,7 +534,6 @@ get_exportlist()
        register struct grouplist *grp, *tgrp;
        struct exportlist **epp;
        struct dirlist *dirhead;
        register struct grouplist *grp, *tgrp;
        struct exportlist **epp;
        struct dirlist *dirhead;
-       struct stat sb;
        struct statfs fsb, *fsp;
        struct hostent *hpe;
        struct ucred anon;
        struct statfs fsb, *fsp;
        struct hostent *hpe;
        struct ucred anon;
@@ -641,8 +641,7 @@ get_exportlist()
                        } else if (*cp == '/') {
                            savedc = *endcp;
                            *endcp = '\0';
                        } else if (*cp == '/') {
                            savedc = *endcp;
                            *endcp = '\0';
-                           if (stat(cp, &sb) >= 0 &&
-                               (sb.st_mode & S_IFMT) == S_IFDIR &&
+                           if (check_dirpath(cp) &&
                                statfs(cp, &fsb) >= 0) {
                                if (got_nondir) {
                                    syslog(LOG_ERR, "Dirs must be first");
                                statfs(cp, &fsb) >= 0) {
                                if (got_nondir) {
                                    syslog(LOG_ERR, "Dirs must be first");
@@ -1981,3 +1980,32 @@ check_options(dp)
        }
        return (0);
 }
        }
        return (0);
 }
+
+/*
+ * Check an absolute directory path for any symbolic links. Return true
+ * if no symbolic links are found.
+ */
+int
+check_dirpath(dirp)
+       register char *dirp;
+{
+       register char *cp;
+       int ret = 1;
+       struct stat sb;
+
+       cp = dirp + 1;
+       while (*cp && ret) {
+               if (*cp == '/') {
+                       *cp = '\0';
+                       if (lstat(dirp, &sb) < 0 ||
+                               (sb.st_mode & S_IFMT) != S_IFDIR)
+                               ret = 0;
+                       *cp = '/';
+               }
+               cp++;
+       }
+       if (lstat(dirp, &sb) < 0 ||
+               (sb.st_mode & S_IFMT) != S_IFDIR)
+               ret = 0;
+       return (ret);
+}