-n option allows access from non-priviledged ports (from cgd)
[unix-history] / usr / src / sbin / mountd / mountd.c
index e22f9dd..029d55f 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.8 (Berkeley) %G%";
+static char sccsid[] = "@(#)mountd.c   8.10 (Berkeley) %G%";
 #endif not lint
 
 #include <sys/param.h>
 #endif not lint
 
 #include <sys/param.h>
@@ -176,7 +176,7 @@ struct ucred def_anon = {
        1,
        { (gid_t) -2 }
 };
        1,
        { (gid_t) -2 }
 };
-int root_only = 1;
+int resvport_only = 1;
 int opt_flags;
 /* Bits for above */
 #define        OP_MAPROOT      0x01
 int opt_flags;
 /* Bits for above */
 #define        OP_MAPROOT      0x01
@@ -213,7 +213,7 @@ main(argc, argv)
        while ((c = getopt(argc, argv, "n")) != EOF)
                switch (c) {
                case 'n':
        while ((c = getopt(argc, argv, "n")) != EOF)
                switch (c) {
                case 'n':
-                       root_only = 0;
+                       resvport_only = 0;
                        break;
                default:
                        fprintf(stderr, "Usage: mountd [-n] [export_file]\n");
                        break;
                default:
                        fprintf(stderr, "Usage: mountd [-n] [export_file]\n");
@@ -277,27 +277,16 @@ mntsrv(rqstp, transp)
        struct exportlist *ep;
        struct dirlist *dp;
        nfsv2fh_t nfh;
        struct exportlist *ep;
        struct dirlist *dp;
        nfsv2fh_t nfh;
-       struct authunix_parms *ucr;
        struct stat stb;
        struct statfs fsb;
        struct hostent *hp;
        u_long saddr;
        struct stat stb;
        struct statfs fsb;
        struct hostent *hp;
        u_long saddr;
+       u_short sport;
        char rpcpath[RPCMNT_PATHLEN+1], dirpath[MAXPATHLEN];
        int bad = ENOENT, omask, defset;
        char rpcpath[RPCMNT_PATHLEN+1], dirpath[MAXPATHLEN];
        int bad = ENOENT, omask, defset;
-       uid_t uid = -2;
-
-       /* Get authorization */
-       switch (rqstp->rq_cred.oa_flavor) {
-       case AUTH_UNIX:
-               ucr = (struct authunix_parms *)rqstp->rq_clntcred;
-               uid = ucr->aup_uid;
-               break;
-       case AUTH_NULL:
-       default:
-               break;
-       }
 
        saddr = transp->xp_raddr.sin_addr.s_addr;
 
        saddr = transp->xp_raddr.sin_addr.s_addr;
+       sport = ntohs(transp->xp_raddr.sin_port);
        hp = (struct hostent *)NULL;
        switch (rqstp->rq_proc) {
        case NULLPROC:
        hp = (struct hostent *)NULL;
        switch (rqstp->rq_proc) {
        case NULLPROC:
@@ -305,7 +294,7 @@ mntsrv(rqstp, transp)
                        syslog(LOG_ERR, "Can't send reply");
                return;
        case RPCMNT_MOUNT:
                        syslog(LOG_ERR, "Can't send reply");
                return;
        case RPCMNT_MOUNT:
-               if ((uid != 0 && root_only) || uid == -2) {
+               if (sport >= IPPORT_RESERVED && resvport_only) {
                        svcerr_weakauth(transp);
                        return;
                }
                        svcerr_weakauth(transp);
                        return;
                }
@@ -315,12 +304,12 @@ mntsrv(rqstp, transp)
                }
 
                /*
                }
 
                /*
-                * Get the real pathname and make sure it is a directory
-                * that exists.
+                * Get the real pathname and make sure it is a file or
+                * directory that exists.
                 */
                if (realpath(rpcpath, dirpath) == 0 ||
                    stat(dirpath, &stb) < 0 ||
                 */
                if (realpath(rpcpath, dirpath) == 0 ||
                    stat(dirpath, &stb) < 0 ||
-                   (stb.st_mode & S_IFMT) != S_IFDIR ||
+                   (!S_ISDIR(stb.st_mode) && !S_ISREG(stb.st_mode)) ||
                    statfs(dirpath, &fsb) < 0) {
                        chdir("/");     /* Just in case realpath doesn't */
                        if (debug)
                    statfs(dirpath, &fsb) < 0) {
                        chdir("/");     /* Just in case realpath doesn't */
                        if (debug)
@@ -374,7 +363,7 @@ mntsrv(rqstp, transp)
                        syslog(LOG_ERR, "Can't send reply");
                return;
        case RPCMNT_UMOUNT:
                        syslog(LOG_ERR, "Can't send reply");
                return;
        case RPCMNT_UMOUNT:
-               if ((uid != 0 && root_only) || uid == -2) {
+               if (sport >= IPPORT_RESERVED && resvport_only) {
                        svcerr_weakauth(transp);
                        return;
                }
                        svcerr_weakauth(transp);
                        return;
                }
@@ -390,7 +379,7 @@ mntsrv(rqstp, transp)
                del_mlist(inet_ntoa(transp->xp_raddr.sin_addr), dirpath);
                return;
        case RPCMNT_UMNTALL:
                del_mlist(inet_ntoa(transp->xp_raddr.sin_addr), dirpath);
                return;
        case RPCMNT_UMNTALL:
-               if ((uid != 0 && root_only) || uid == -2) {
+               if (sport >= IPPORT_RESERVED && resvport_only) {
                        svcerr_weakauth(transp);
                        return;
                }
                        svcerr_weakauth(transp);
                        return;
                }
@@ -1965,15 +1954,13 @@ check_dirpath(dirp)
        while (*cp && ret) {
                if (*cp == '/') {
                        *cp = '\0';
        while (*cp && ret) {
                if (*cp == '/') {
                        *cp = '\0';
-                       if (lstat(dirp, &sb) < 0 ||
-                               (sb.st_mode & S_IFMT) != S_IFDIR)
+                       if (lstat(dirp, &sb) < 0 || !S_ISDIR(sb.st_mode))
                                ret = 0;
                        *cp = '/';
                }
                cp++;
        }
                                ret = 0;
                        *cp = '/';
                }
                cp++;
        }
-       if (lstat(dirp, &sb) < 0 ||
-               (sb.st_mode & S_IFMT) != S_IFDIR)
+       if (lstat(dirp, &sb) < 0 || !S_ISDIR(sb.st_mode))
                ret = 0;
        return (ret);
 }
                ret = 0;
        return (ret);
 }