summaryrefslogtreecommitdiff
path: root/inet/rcmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'inet/rcmd.c')
-rw-r--r--inet/rcmd.c50
1 files changed, 31 insertions, 19 deletions
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. */
}
}