about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--NEWS36
-rw-r--r--inet/rcmd.c50
3 files changed, 55 insertions, 37 deletions
diff --git a/ChangeLog b/ChangeLog
index 2ccf739ae4..86a3144254 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2015-06-18  Carlos O'Donell  <carlos@redhat.com>
+
+	[BZ #18557]
+	* inet/rcmd.c (__validuser2_sa): Check user first to
+	short-circuit host check.
+
 2015-07-07  Pavel Kopyl  <p.kopyl@samsung.com>
 	    Mikhail Ilin  <m.ilin@samsung.com>
 
diff --git a/NEWS b/NEWS
index a809ce2273..c316cabb8f 100644
--- a/NEWS
+++ b/NEWS
@@ -9,24 +9,24 @@ Version 2.22
 
 * The following bugs are resolved with this release:
 
-  438, 4719, 6792, 13028, 13064, 14094, 14841, 14906, 14958, 15319, 15467,
-  15790, 15969, 16159, 16339, 16350, 16351, 16352, 16353, 16361, 16512,
-  16526, 16538, 16559, 16560, 16704, 16783, 16850, 17053, 17090, 17195,
-  17269, 17293, 17322, 17403, 17523, 17542, 17569, 17581, 17588, 17596,
-  17620, 17621, 17628, 17631, 17692, 17711, 17715, 17776, 17779, 17792,
-  17833, 17836, 17841, 17912, 17916, 17930, 17932, 17944, 17949, 17964,
-  17965, 17967, 17969, 17977, 17978, 17987, 17991, 17996, 17998, 17999,
-  18007, 18019, 18020, 18029, 18030, 18032, 18034, 18036, 18038, 18039,
-  18042, 18043, 18046, 18047, 18049, 18068, 18080, 18093, 18100, 18104,
-  18110, 18111, 18116, 18125, 18128, 18138, 18185, 18196, 18197, 18206,
-  18210, 18211, 18217, 18219, 18220, 18221, 18234, 18244, 18245, 18247,
-  18287, 18319, 18324, 18333, 18346, 18371, 18397, 18409, 18410, 18412,
-  18418, 18422, 18434, 18435, 18444, 18468, 18469, 18470, 18479, 18483,
-  18495, 18496, 18497, 18498, 18502, 18507, 18508, 18512, 18513, 18519,
-  18520, 18522, 18527, 18528, 18529, 18530, 18532, 18533, 18534, 18536,
-  18539, 18540, 18542, 18544, 18545, 18546, 18547, 18549, 18553, 18558,
-  18569, 18583, 18585, 18586, 18592, 18593, 18594, 18602, 18612, 18613,
-  18619, 18633.
+  438, 4719, 6792, 13028, 13064, 14094, 14841, 14906, 14958, 15319,
+  15467, 15790, 15969, 16159, 16339, 16350, 16351, 16352, 16353, 16361,
+  16512, 16526, 16538, 16559, 16560, 16704, 16783, 16850, 17053, 17090,
+  17195, 17269, 17293, 17322, 17403, 17523, 17542, 17569, 17581, 17588,
+  17596, 17620, 17621, 17628, 17631, 17692, 17711, 17715, 17776, 17779,
+  17792, 17833, 17836, 17841, 17912, 17916, 17930, 17932, 17944, 17949,
+  17964, 17965, 17967, 17969, 17977, 17978, 17987, 17991, 17996, 17998,
+  17999, 18007, 18019, 18020, 18029, 18030, 18032, 18034, 18036, 18038,
+  18039, 18042, 18043, 18046, 18047, 18049, 18068, 18080, 18093, 18100,
+  18104, 18110, 18111, 18116, 18125, 18128, 18138, 18185, 18196, 18197,
+  18206, 18210, 18211, 18217, 18219, 18220, 18221, 18234, 18244, 18245,
+  18247, 18287, 18319, 18324, 18333, 18346, 18371, 18397, 18409, 18410,
+  18412, 18418, 18422, 18434, 18435, 18444, 18468, 18469, 18470, 18479,
+  18483, 18495, 18496, 18497, 18498, 18502, 18507, 18508, 18512, 18513,
+  18519, 18520, 18522, 18527, 18528, 18529, 18530, 18532, 18533, 18534,
+  18536, 18539, 18540, 18542, 18544, 18545, 18546, 18547, 18549, 18553,
+  18557, 18558, 18569, 18583, 18585, 18586, 18592, 18593, 18594, 18602,
+  18612, 18613, 18619, 18633.
 
 * Cache information can be queried via sysconf() function on s390 e.g. with
   _SC_LEVEL1_ICACHE_SIZE as argument.
diff --git a/inet/rcmd.c b/inet/rcmd.c
index 98b3735d1f..035cb0d87d 100644
--- a/inet/rcmd.c
+++ b/inet/rcmd.c
@@ -809,31 +809,43 @@ __validuser2_sa(hostf, ra, ralen, luser, ruser, rhost)
 	*p = '\0';              /* <nul> terminate username (+host?) */
 
 	/* buf -> host(?) ; user -> username(?) */
+	if (*buf == '\0')
+	  break;
+	if (*user == '\0')
+	  user = luser;
+
+	/* First check the user part.  In a naive implementation we
+	   would check the host part first, then the user.  However,
+	   if we check the user first and reject the entry we will
+	   have saved doing any host lookups to normalize the comparison
+	   and that likely saves several DNS queries.  Therefore we
+	   check the user first.  */
+	ucheck = __icheckuser (user, ruser);
+
+	/* Either we found the user, or we didn't and this is a
+	   negative host check.  We must do the negative host lookup
+	   in order to preserve the semantics of stopping on this line
+	   before processing others.  */
+	if (ucheck != 0 || *buf == '-') {
+
+	    /* Next check host part.  */
+	    hcheck = __checkhost_sa (ra, ralen, buf, rhost);
+
+	    /* Negative '-host user(?)' match?  */
+	    if (hcheck < 0)
+		break;
 
-	/* First check host part */
-	hcheck = __checkhost_sa (ra, ralen, buf, rhost);
-
-	if (hcheck < 0)
-	    break;
-
-	if (hcheck) {
-	    /* Then check user part */
-	    if (! (*user))
-		user = luser;
-
-	    ucheck = __icheckuser (user, ruser);
-
-	    /* Positive 'host user' match? */
-	    if (ucheck > 0) {
+	    /* Positive 'host user' match?  */
+	    if (hcheck > 0 && ucheck > 0) {
 		retval = 0;
 		break;
 	    }
 
-	    /* Negative 'host -user' match? */
-	    if (ucheck < 0)
-		break;
+	    /* Negative 'host -user' match?  */
+	    if (hcheck > 0 && ucheck < 0)
+	      break;
 
-	    /* Neither, go on looking for match */
+	    /* Neither, go on looking for match.  */
 	}
     }