[Midnightbsd-cvs] src [8185] trunk/usr.sbin/mountd/mountd.c: Attila Bogar reported a bug in mountd when multiple export

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Sat Sep 17 11:31:55 EDT 2016


Revision: 8185
          http://svnweb.midnightbsd.org/src/?rev=8185
Author:   laffer1
Date:     2016-09-17 11:31:55 -0400 (Sat, 17 Sep 2016)
Log Message:
-----------
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.

Obtained from: FreeBSD

Modified Paths:
--------------
    trunk/usr.sbin/mountd/mountd.c

Modified: trunk/usr.sbin/mountd/mountd.c
===================================================================
--- trunk/usr.sbin/mountd/mountd.c	2016-09-17 15:12:12 UTC (rev 8184)
+++ trunk/usr.sbin/mountd/mountd.c	2016-09-17 15:31:55 UTC (rev 8185)
@@ -117,6 +117,8 @@
 	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 @@
 	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 @@
 /* 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 @@
 	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 @@
 		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 @@
 				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 @@
 				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 @@
 			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 @@
 		 */
 		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 @@
  */
 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 @@
 	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 @@
 			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 @@
  */
 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 @@
 					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 @@
 				    (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 @@
 	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);



More information about the Midnightbsd-cvs mailing list