Author: rmacklem
Date: Mon Oct  8 12:59:09 2012
New Revision: 241347
URL: http://svn.freebsd.org/changeset/base/241347

Log:
  MFC: r240902
  Attila Bogar reported a bug in mountd when multiple export
  entries with different security flavors are in the exports(5)
  file. For that case, mountd replies with the security flavors
  of the last entry and not the correct one for the client host.
  This patch fixes that by storing separate copies of the flavors
  for each host/net case, plus a default one for the case where
  no hosts/nets are specified on an entry in the exports(5) file.
  Unlike the patch in the PR, it replies with the security flavors
  for the entry instead of merging the security flavors for all
  the entries and replying with that.

Modified:
  stable/9/usr.sbin/mountd/mountd.c
Directory Properties:
  stable/9/usr.sbin/mountd/   (props changed)

Modified: stable/9/usr.sbin/mountd/mountd.c
==============================================================================
--- stable/9/usr.sbin/mountd/mountd.c   Mon Oct  8 10:43:59 2012        
(r241346)
+++ stable/9/usr.sbin/mountd/mountd.c   Mon Oct  8 12:59:09 2012        
(r241347)
@@ -117,6 +117,8 @@ struct exportlist {
        char            *ex_indexfile;
        int             ex_numsecflavors;
        int             ex_secflavors[MAXSECFLAVORS];
+       int             ex_defnumsecflavors;
+       int             ex_defsecflavors[MAXSECFLAVORS];
 };
 /* ex_flag bits */
 #define        EX_LINKED       0x1
@@ -136,6 +138,8 @@ struct grouplist {
        int gr_type;
        union grouptypes gr_ptr;
        struct grouplist *gr_next;
+       int gr_numsecflavors;
+       int gr_secflavors[MAXSECFLAVORS];
 };
 /* Group types */
 #define        GT_NULL         0x0
@@ -163,12 +167,13 @@ struct fhreturn {
 /* Global defs */
 char   *add_expdir(struct dirlist **, char *, int);
 void   add_dlist(struct dirlist **, struct dirlist *,
-                               struct grouplist *, int);
+                               struct grouplist *, int, struct exportlist *);
 void   add_mlist(char *, char *);
 int    check_dirpath(char *);
 int    check_options(struct dirlist *);
 int    checkmask(struct sockaddr *sa);
-int    chk_host(struct dirlist *, struct sockaddr *, int *, int *);
+int    chk_host(struct dirlist *, struct sockaddr *, int *, int *, int *,
+                                int **);
 static int     create_service(struct netconfig *nconf);
 static void    complete_service(struct netconfig *nconf, char *port_str);
 static void    clearout_service(void);
@@ -938,6 +943,7 @@ mntsrv(struct svc_req *rqstp, SVCXPRT *t
        char rpcpath[MNTPATHLEN + 1], dirpath[MAXPATHLEN];
        int bad = 0, defset, hostset;
        sigset_t sighup_mask;
+       int numsecflavors, *secflavorsp;
 
        sigemptyset(&sighup_mask);
        sigaddset(&sighup_mask, SIGHUP);
@@ -1000,9 +1006,11 @@ mntsrv(struct svc_req *rqstp, SVCXPRT *t
                sigprocmask(SIG_BLOCK, &sighup_mask, NULL);
                ep = ex_search(&fsb.f_fsid);
                hostset = defset = 0;
-               if (ep && (chk_host(ep->ex_defdir, saddr, &defset, &hostset) ||
+               if (ep && (chk_host(ep->ex_defdir, saddr, &defset, &hostset,
+                   &numsecflavors, &secflavorsp) ||
                    ((dp = dirp_search(ep->ex_dirl, dirpath)) &&
-                     chk_host(dp, saddr, &defset, &hostset)) ||
+                     chk_host(dp, saddr, &defset, &hostset, &numsecflavors,
+                      &secflavorsp)) ||
                    (defset && scan_tree(ep->ex_defdir, saddr) == 0 &&
                     scan_tree(ep->ex_dirl, saddr) == 0))) {
                        if (bad) {
@@ -1012,10 +1020,15 @@ mntsrv(struct svc_req *rqstp, SVCXPRT *t
                                sigprocmask(SIG_UNBLOCK, &sighup_mask, NULL);
                                return;
                        }
-                       if (hostset & DP_HOSTSET)
+                       if (hostset & DP_HOSTSET) {
                                fhr.fhr_flag = hostset;
-                       else
+                               fhr.fhr_numsecflavors = numsecflavors;
+                               fhr.fhr_secflavors = secflavorsp;
+                       } else {
                                fhr.fhr_flag = defset;
+                               fhr.fhr_numsecflavors = ep->ex_defnumsecflavors;
+                               fhr.fhr_secflavors = ep->ex_defsecflavors;
+                       }
                        fhr.fhr_vers = rqstp->rq_vers;
                        /* Get the file handle */
                        memset(&fhr.fhr_fh, 0, sizeof(nfsfh_t));
@@ -1028,8 +1041,6 @@ mntsrv(struct svc_req *rqstp, SVCXPRT *t
                                sigprocmask(SIG_UNBLOCK, &sighup_mask, NULL);
                                return;
                        }
-                       fhr.fhr_numsecflavors = ep->ex_numsecflavors;
-                       fhr.fhr_secflavors = ep->ex_secflavors;
                        if (!svc_sendreply(transp, (xdrproc_t)xdr_fhs,
                            (caddr_t)&fhr))
                                syslog(LOG_ERR, "can't send reply");
@@ -1884,11 +1895,21 @@ hang_dirp(struct dirlist *dp, struct gro
                        ep->ex_defdir = dp;
                if (grp == (struct grouplist *)NULL) {
                        ep->ex_defdir->dp_flag |= DP_DEFSET;
+                       /* Save the default security flavors list. */
+                       ep->ex_defnumsecflavors = ep->ex_numsecflavors;
+                       if (ep->ex_numsecflavors > 0)
+                               memcpy(ep->ex_defsecflavors, ep->ex_secflavors,
+                                   sizeof(ep->ex_secflavors));
                } else while (grp) {
                        hp = get_ht();
                        hp->ht_grp = grp;
                        hp->ht_next = ep->ex_defdir->dp_hosts;
                        ep->ex_defdir->dp_hosts = hp;
+                       /* Save the security flavors list for this host set. */
+                       grp->gr_numsecflavors = ep->ex_numsecflavors;
+                       if (ep->ex_numsecflavors > 0)
+                               memcpy(grp->gr_secflavors, ep->ex_secflavors,
+                                   sizeof(ep->ex_secflavors));
                        grp = grp->gr_next;
                }
        } else {
@@ -1898,7 +1919,7 @@ hang_dirp(struct dirlist *dp, struct gro
                 */
                while (dp) {
                        dp2 = dp->dp_left;
-                       add_dlist(&ep->ex_dirl, dp, grp, flags);
+                       add_dlist(&ep->ex_dirl, dp, grp, flags, ep);
                        dp = dp2;
                }
        }
@@ -1910,7 +1931,7 @@ hang_dirp(struct dirlist *dp, struct gro
  */
 void
 add_dlist(struct dirlist **dpp, struct dirlist *newdp, struct grouplist *grp,
-       int flags)
+       int flags, struct exportlist *ep)
 {
        struct dirlist *dp;
        struct hostlist *hp;
@@ -1920,10 +1941,10 @@ add_dlist(struct dirlist **dpp, struct d
        if (dp) {
                cmp = strcmp(dp->dp_dirp, newdp->dp_dirp);
                if (cmp > 0) {
-                       add_dlist(&dp->dp_left, newdp, grp, flags);
+                       add_dlist(&dp->dp_left, newdp, grp, flags, ep);
                        return;
                } else if (cmp < 0) {
-                       add_dlist(&dp->dp_right, newdp, grp, flags);
+                       add_dlist(&dp->dp_right, newdp, grp, flags, ep);
                        return;
                } else
                        free((caddr_t)newdp);
@@ -1942,10 +1963,20 @@ add_dlist(struct dirlist **dpp, struct d
                        hp->ht_grp = grp;
                        hp->ht_next = dp->dp_hosts;
                        dp->dp_hosts = hp;
+                       /* Save the security flavors list for this host set. */
+                       grp->gr_numsecflavors = ep->ex_numsecflavors;
+                       if (ep->ex_numsecflavors > 0)
+                               memcpy(grp->gr_secflavors, ep->ex_secflavors,
+                                   sizeof(ep->ex_secflavors));
                        grp = grp->gr_next;
                } while (grp);
        } else {
                dp->dp_flag |= DP_DEFSET;
+               /* Save the default security flavors list. */
+               ep->ex_defnumsecflavors = ep->ex_numsecflavors;
+               if (ep->ex_numsecflavors > 0)
+                       memcpy(ep->ex_defsecflavors, ep->ex_secflavors,
+                           sizeof(ep->ex_secflavors));
        }
 }
 
@@ -1974,7 +2005,7 @@ dirp_search(struct dirlist *dp, char *di
  */
 int
 chk_host(struct dirlist *dp, struct sockaddr *saddr, int *defsetp,
-       int *hostsetp)
+       int *hostsetp, int *numsecflavors, int **secflavorsp)
 {
        struct hostlist *hp;
        struct grouplist *grp;
@@ -1993,6 +2024,12 @@ chk_host(struct dirlist *dp, struct sock
                                        if (!sacmp(ai->ai_addr, saddr, NULL)) {
                                                *hostsetp =
                                                    (hp->ht_flag | DP_HOSTSET);
+                                               if (numsecflavors != NULL) {
+                                                       *numsecflavors =
+                                                           
grp->gr_numsecflavors;
+                                                       *secflavorsp =
+                                                           grp->gr_secflavors;
+                                               }
                                                return (1);
                                        }
                                }
@@ -2003,6 +2040,12 @@ chk_host(struct dirlist *dp, struct sock
                                    (struct sockaddr *)
                                    &grp->gr_ptr.gt_net.nt_mask)) {
                                        *hostsetp = (hp->ht_flag | DP_HOSTSET);
+                                       if (numsecflavors != NULL) {
+                                               *numsecflavors =
+                                                   grp->gr_numsecflavors;
+                                               *secflavorsp =
+                                                   grp->gr_secflavors;
+                                       }
                                        return (1);
                                }
                                break;
@@ -2024,7 +2067,7 @@ scan_tree(struct dirlist *dp, struct soc
        if (dp) {
                if (scan_tree(dp->dp_left, saddr))
                        return (1);
-               if (chk_host(dp, saddr, &defset, &hostset))
+               if (chk_host(dp, saddr, &defset, &hostset, NULL, NULL))
                        return (1);
                if (scan_tree(dp->dp_right, saddr))
                        return (1);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to