You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Dean Gaudet <dg...@arctic.org> on 1997/07/27 09:08:49 UTC

[PATCH] mod_access overhaul (take 2)

This one adds "HostnameLookups double", and fixes up the hostnamelookups
documentation.  I didn't test it as hard as I did the last one... it's
quake o' clock. 

Oh yeah it bitfields a few things in the core dir config.  Why do I
bitfield?  'cause I dislike using an int as essentially a boolean in a
structure that gets allocated many many times.  Smaller memory footprint
means smaller cache footprint (means faster!). 

BTW it's surprising the number of tristate fields whose names or
descriptions make them sound like booleans.  content_md5, do_rfc1413,
keepalive, hostname_lookups (pre-this patch).

Dean

Index: htdocs/manual/mod/core.html
===================================================================
RCS file: /export/home/cvs/apache/htdocs/manual/mod/core.html,v
retrieving revision 1.67
diff -u -r1.67 core.html
--- core.html	1997/07/21 21:26:55	1.67
+++ core.html	1997/07/27 07:02:43
@@ -575,16 +575,40 @@
 
 <h2><A name="hostnamelookups">HostNameLookups directive</A></h2>
 <!--%plaintext &lt;?INDEX {\tt HostNameLookups} directive&gt; -->
-<strong>Syntax:</strong> HostNameLookups <em>boolean</em><br>
-<strong>Default:</strong> <code>HostNameLookups on</code><br>
+<strong>Syntax:</strong> HostNameLookups <em>on | off | double</em><br>
+<strong>Default:</strong> <code>HostNameLookups off</code><br>
 <strong>Context:</strong> server config, virtual host<br>
-<strong>Status:</strong> core<p>
+<strong>Status:</strong> core<br>
+<strong>Compatibility:</strong> <code>double</code> available only in Apache
+1.3 and above.<br>
+<strong>Compatibility:</strong> Default was <code>on</code> prior to Apache
+1.3.<p>
 
-This directive enables DNS lookups so that host names can be logged.
-Having this directive set <code>on</code> also enables the use of names
-in &lt;Limit&gt; blocks for access control.<p>
+This directive enables DNS lookups so that host names can be logged (and
+passed to CGIs/SSIs in <code>REMOTE_HOST</code>).
+The value <code>double</code> refers to doing double-reverse DNS.
+That is, after a reverse lookup is performed, a forward lookup is then
+performed on that result.  At least one of the ip addresses in the forward
+lookup must match the original address.  (In "tcpwrappers" terminology
+this is called <code>PARANOID</code>.)<p>
 
-Heavily loaded sites should set this directive <code>off</code>, since DNS
+Regardless of the setting, when <a href="mod_access.html">mod_access</a>
+is used for controlling access by hostname, a double reverse lookup
+will be performed.  This is necessary for security.  Note that the
+result of this double-reverse isn't generally available unless
+you set <code>HostnameLookups double</code>.  For example, if only
+<code>HostnameLookups on</code> and a request is made to an object that
+is protected by hostname restrictions, regardless of whether the
+double-reverse fails or not, CGIs will still be passed the single-reverse
+result in <code>REMOTE_HOST</code>.<p>
+
+The default for this directive was previously <code>on</code> in
+versions of Apache prior to 1.3.  It was changed to <code>off</code>
+in order to save the network traffic for those sites that don't truly
+need the reverse lookups done.  It is also better for the end users
+because they don't have to suffer the extra latency that a lookup
+entails.
+Heavily loaded sites should leave this directive <code>off</code>, since DNS
 lookups can take considerable amounts of time. The utility <i>logresolve</i>,
 provided in the <i>/support</i> directory, can be used to look up host names
 from logged IP addresses offline.<p><hr>
Index: htdocs/manual/mod/mod_access.html
===================================================================
RCS file: /export/home/cvs/apache/htdocs/manual/mod/mod_access.html,v
retrieving revision 1.9
diff -u -r1.9 mod_access.html
--- mod_access.html	1997/07/06 17:19:14	1.9
+++ mod_access.html	1997/07/27 07:02:44
@@ -53,6 +53,12 @@
 <dd>An IP address of a host allowed access
 <dt>A partial IP address
 <dd>The first 1 to 3 bytes of an IP address, for subnet restriction.
+<dt>A network/netmask pair
+<dd>A network a.b.c.d, and a netmask w.x.y.z.  For more fine-grained subnet
+    restriction.  (i.e. 10.1.0.0/255.255.0.0)
+<dt>A network/nnn CIDR specification
+<dd>Similar to the previous case, except the netmask consists of nnn 
+    high-order 1 bits.  (i.e. 10.1.0.0/16 is the same as 10.1.0.0/255.255.0.0)
 </dl>
 <P>
 Example:
@@ -121,6 +127,12 @@
 <dd>An IP address of a host denied access
 <dt>A partial IP address
 <dd>The first 1 to 3 bytes of an IP address, for subnet restriction.
+<dt>A network/netmask pair
+<dd>A network a.b.c.d, and a netmask w.x.y.z.  For more fine-grained subnet
+    restriction.  (i.e. 10.1.0.0/255.255.0.0)
+<dt>A network/nnn CIDR specification
+<dd>Similar to the previous case, except the netmask consists of nnn 
+    high-order 1 bits.  (i.e. 10.1.0.0/16 is the same as 10.1.0.0/255.255.0.0)
 </dl>
 <P>
 Example:
Index: src/CHANGES
===================================================================
RCS file: /export/home/cvs/apache/src/CHANGES,v
retrieving revision 1.368
diff -u -r1.368 CHANGES
--- CHANGES	1997/07/27 02:38:03	1.368
+++ CHANGES	1997/07/27 07:02:56
@@ -1,5 +1,19 @@
 Changes with Apache 1.3a2
 
+  *) mod_access overhaul:
+     - Now understands network/netmask syntax (i.e.  10.1.0.0/255.255.0.0)
+	and cidr syntax (i.e. 10.1.0.0/16).
+     - Critical path was sped up by pre-computing a few things at config
+	time.
+     - The undocumented syntax "allow user-agents" was removed,
+	the replacement is "allow from env=foobar" combined with mod_browser.
+     - When used with hostnames it now forces a double-reverse lookup
+	no matter what the directory settings are.  This double-reverse
+	doesn't affect any of the other routines that use the remote
+	hostname.  In particular it's still passed to CGIs and the log
+	without the double-reverse check.
+     [Dean Gaudet]
+
   *) mod_cern_meta would attempt to find meta files for the directory itself
      in some cases, but not in others.  It now avoids it in all cases.
      [Dean Gaudet]
Index: src/http_core.c
===================================================================
RCS file: /export/home/cvs/apache/src/http_core.c,v
retrieving revision 1.100
diff -u -r1.100 http_core.c
--- http_core.c	1997/07/24 04:38:09	1.100
+++ http_core.c	1997/07/27 07:03:00
@@ -84,7 +84,7 @@
     if (!dir || dir[strlen(dir) - 1] == '/') conf->d = dir;
     else if (strncmp(dir,"proxy:",6)==0) conf->d = pstrdup (a, dir);
     else conf->d = pstrcat (a, dir, "/", NULL);
-    conf->d_is_matchexp = conf->d ? is_matchexp( conf->d ) : 0;
+    conf->d_is_matchexp = conf->d ? (is_matchexp( conf->d ) != 0) : 0;
 
 
     conf->opts = dir ? OPT_UNSET : OPT_ALL;
@@ -93,7 +93,7 @@
 
     conf->content_md5 = 2;
 
-    conf->hostname_lookups = 2;/* binary, but will use 2 as an "unset = on" */
+    conf->hostname_lookups = HOSTNAME_LOOKUP_UNSET;
     conf->do_rfc1413 = DEFAULT_RFC1413 | 2;  /* set bit 1 to indicate default */
     conf->satisfy = SATISFY_NOSPEC;
 
@@ -155,7 +155,7 @@
 		conf->response_code_strings[i] = new->response_code_strings[i];
 	}
     }
-    if (new->hostname_lookups != 2)
+    if (new->hostname_lookups != HOSTNAME_LOOKUP_UNSET)
 	conf->hostname_lookups = new->hostname_lookups;
     if ((new->do_rfc1413 & 2) == 0) conf->do_rfc1413 = new->do_rfc1413;
     if ((new->content_md5 & 2) == 0) conf->content_md5 = new->content_md5;
@@ -324,20 +324,46 @@
     return conf->response_code_strings[error_index];
 }
 
+
+/* Code from Harald Hanche-Olsen <ha...@imf.unit.no> */
+static void inline do_double_reverse (conn_rec *conn)
+{
+    struct hostent *hptr;
+    char **haddr;
+
+    if (conn->double_reverse) {
+	/* already done */
+	return;
+    }
+    hptr = gethostbyname(conn->remote_host);
+    if (hptr) {
+	for (haddr = hptr->h_addr_list; *haddr; haddr++) {
+	    if (((struct in_addr *)(*haddr))->s_addr
+		== conn->remote_addr.sin_addr.s_addr) {
+		break;
+	    }
+	}
+    }
+    if (!hptr || !*haddr) {
+	conn->double_reverse = -1;
+    } else {
+	conn->double_reverse = 1;
+    }
+}
+
 API_EXPORT(const char *) get_remote_host(conn_rec *conn, void *dir_config, int type)
 {
     struct in_addr *iaddr;
     struct hostent *hptr;
-#ifdef MAXIMUM_DNS
-    char **haddr;
-#endif
     core_dir_config *dir_conf = NULL;
 
 /* If we haven't checked the host name, and we want to */
     if (dir_config) 
 	dir_conf = (core_dir_config *)get_module_config(dir_config, &core_module);
 
-   if ((!dir_conf) || (type != REMOTE_NOLOOKUP && conn->remote_host == NULL && dir_conf->hostname_lookups))
+   if ((!dir_conf) || (type != REMOTE_NOLOOKUP && conn->remote_host == NULL
+	&& (type == REMOTE_DOUBLE_REV
+	    || dir_conf->hostname_lookups != HOSTNAME_LOOKUP_OFF)))
     {
 #ifdef STATUS
 	int old_stat = update_child_status(conn->child_num,
@@ -346,25 +372,17 @@
 #endif /* STATUS */
 	iaddr = &(conn->remote_addr.sin_addr);
 	hptr = gethostbyaddr((char *)iaddr, sizeof(struct in_addr), AF_INET);
-	if (hptr != NULL)
-	{
+	if (hptr != NULL) {
 	    conn->remote_host = pstrdup(conn->pool, (void *)hptr->h_name);
 	    str_tolower (conn->remote_host);
 	   
-#ifdef MAXIMUM_DNS
-    /* Grrr. Check THAT name to make sure it's really the name of the addr. */
-    /* Code from Harald Hanche-Olsen <ha...@imf.unit.no> */
-
-	    hptr = gethostbyname(conn->remote_host);
-	    if (hptr)
-	    {
-		for(haddr=hptr->h_addr_list; *haddr; haddr++)
-		    if(((struct in_addr *)(*haddr))->s_addr == iaddr->s_addr)
-			break;
+	    if (dir_conf
+		&& dir_conf->hostname_lookups == HOSTNAME_LOOKUP_DOUBLE) {
+		do_double_reverse (conn);
+		if (conn->double_reverse != 1) {
+		    conn->remote_host = NULL;
+		}
 	    }
-	    if((!hptr) || (!(*haddr)))
-		conn->remote_host = NULL;
-#endif
 	}
 /* if failed, set it to the NULL string to indicate error */
 	if (conn->remote_host == NULL) conn->remote_host = "";
@@ -372,6 +390,12 @@
 	(void)update_child_status(conn->child_num,old_stat,(request_rec*)NULL);
 #endif /* STATUS */
     }
+    if (type == REMOTE_DOUBLE_REV) {
+	do_double_reverse (conn);
+	if (conn->double_reverse == -1) {
+	    return NULL;
+	}
+    }
 
 /*
  * Return the desired information; either the remote DNS name, if found,
@@ -382,7 +406,7 @@
 	return conn->remote_host;
     else
     {
-	if (type == REMOTE_HOST) return NULL;
+	if (type == REMOTE_HOST || type == REMOTE_DOUBLE_REV) return NULL;
 	else return conn->remote_ip;
     }
 }
@@ -695,7 +719,7 @@
 
     conf = (core_dir_config *)get_module_config(new_url_conf, &core_module);
     conf->d = pstrdup(cmd->pool, cmd->path);	/* No mangling, please */
-    conf->d_is_matchexp = is_matchexp( conf->d );
+    conf->d_is_matchexp = is_matchexp( conf->d ) != 0;
     conf->r = r;
 
     add_per_url_conf (cmd->server, new_url_conf);
@@ -751,7 +775,7 @@
 
     conf = (core_dir_config *)get_module_config(new_file_conf, &core_module);
     conf->d = pstrdup(cmd->pool, cmd->path);
-    conf->d_is_matchexp = is_matchexp( conf->d );
+    conf->d_is_matchexp = is_matchexp( conf->d ) != 0;
     conf->r = r;
 
     add_file_conf (c, new_file_conf);
@@ -985,13 +1009,21 @@
 }
 
 const char *set_idcheck (cmd_parms *cmd, core_dir_config *d, int arg) {
-    d->do_rfc1413 = arg;
+    d->do_rfc1413 = arg != 0;
     return NULL;
 }
 
-const char *set_hostname_lookups (cmd_parms *cmd, core_dir_config *d, int arg)
+const char *set_hostname_lookups (cmd_parms *cmd, core_dir_config *d, char *arg)
 {
-    d->hostname_lookups = arg;
+    if (strcasecmp (arg, "on")) {
+	d->hostname_lookups = HOSTNAME_LOOKUP_ON;
+    } else if (strcasecmp (arg, "off")) {
+	d->hostname_lookups = HOSTNAME_LOOKUP_OFF;
+    } else if (strcasecmp (arg, "double")) {
+	d->hostname_lookups = HOSTNAME_LOOKUP_DOUBLE;
+    } else {
+	return "parameter must be 'on', 'off', or 'double'";
+    }
     return NULL;
 }
 
@@ -1002,7 +1034,7 @@
 }
 
 const char *set_content_md5 (cmd_parms *cmd, core_dir_config *d, int arg) {
-    d->content_md5 = arg;
+    d->content_md5 = arg != 0;
     return NULL;
 }
 
@@ -1245,7 +1277,7 @@
 
 { "ServerType", server_type, NULL, RSRC_CONF, TAKE1,"'inetd' or 'standalone'"},
 { "Port", server_port, NULL, RSRC_CONF, TAKE1, "A TCP port number"},
-{ "HostnameLookups", set_hostname_lookups, NULL, ACCESS_CONF|RSRC_CONF, FLAG, "\"on\" to enable or \"off\" to disable reverse DNS lookups" },
+{ "HostnameLookups", set_hostname_lookups, NULL, ACCESS_CONF|RSRC_CONF, TAKE1, "\"on\" to enable, \"off\" to disable reverse DNS lookups, or \"double\" to enable double-reverse DNS lookups" },
 { "User", set_user, NULL, RSRC_CONF, TAKE1, "Effective user id for this server"},
 { "Group", set_group, NULL, RSRC_CONF, TAKE1, "Effective group id for this server"},
 { "ServerAdmin", set_server_string_slot,
Index: src/http_core.h
===================================================================
RCS file: /export/home/cvs/apache/src/http_core.h,v
retrieving revision 1.24
diff -u -r1.24 http_core.h
--- http_core.h	1997/07/16 00:41:21	1.24
+++ http_core.h	1997/07/27 07:03:00
@@ -77,6 +77,7 @@
 #define REMOTE_HOST (0)
 #define REMOTE_NAME (1)
 #define REMOTE_NOLOOKUP (2)
+#define REMOTE_DOUBLE_REV (3)
 
 #define SATISFY_ALL 0
 #define SATISFY_ANY 1
@@ -128,12 +129,8 @@
 typedef unsigned char overrides_t;
 
 typedef struct {
+    /* path of the directory/regex/etc.  see also d_is_matchexp below */
     char *d;
-    /* since is_matchexp(conf->d) was being called so frequently in
-     * directory_walk() and its relatives, this field was created and
-     * is set to the result of that call.
-     */
-    int d_is_matchexp;
 
     allow_options_t opts;
     allow_options_t opts_add;
@@ -154,8 +151,6 @@
     char *auth_name;
     array_header *requires;
 
-    int content_md5;
-    
     /* Custom response config. These can contain text or a URL to redirect to.
      * if response_code_strings is NULL then there are none in the config,
      * if it's not null then it's allocated to sizeof(char*)*RESPONSE_CODES.
@@ -165,8 +160,21 @@
     char **response_code_strings;
 
     /* Hostname resolution etc */
-    int hostname_lookups;
-    int do_rfc1413;   /* See if client is advertising a username? */
+#define HOSTNAME_LOOKUP_OFF	0
+#define HOSTNAME_LOOKUP_ON	1
+#define HOSTNAME_LOOKUP_DOUBLE	2
+#define HOSTNAME_LOOKUP_UNSET	3
+    int hostname_lookups : 4;
+
+    int do_rfc1413 : 2;   /* See if client is advertising a username? */
+
+    int content_md5 : 2;  /* calculate Content-MD5? */
+
+    /* since is_matchexp(conf->d) was being called so frequently in
+     * directory_walk() and its relatives, this field was created and
+     * is set to the result of that call.
+     */
+    int d_is_matchexp : 1;
 
     /* System Resource Control */
 #ifdef RLIMIT_CPU
Index: src/http_protocol.c
===================================================================
RCS file: /export/home/cvs/apache/src/http_protocol.c,v
retrieving revision 1.145
diff -u -r1.145 http_protocol.c
--- http_protocol.c	1997/07/24 04:23:58	1.145
+++ http_protocol.c	1997/07/27 07:03:06
@@ -772,7 +772,7 @@
     r->server = conn->server;
     r->pool = make_sub_pool(conn->pool);
 
-    conn->keptalive = conn->keepalive;
+    conn->keptalive = conn->keepalive == 1;
     conn->keepalive = 0;
 
     conn->user = NULL;
Index: src/httpd.h
===================================================================
RCS file: /export/home/cvs/apache/src/httpd.h,v
retrieving revision 1.133
diff -u -r1.133 httpd.h
--- httpd.h	1997/07/27 02:15:46	1.133
+++ httpd.h	1997/07/27 07:03:08
@@ -581,7 +581,6 @@
 
   int child_num;                /* The number of the child handling conn_rec */
   BUFF *client;			/* Connection to the guy */
-  int aborted;			/* Are we still talking? */
   
   /* Who is the client? */
   
@@ -602,8 +601,12 @@
 				 */
   char *auth_type;		/* Ditto. */
 
-  int keepalive;		/* Are we using HTTP Keep-Alive? */
-  int keptalive;		/* Did we use HTTP Keep-Alive? */
+  int aborted : 1;		/* Are we still talking? */
+  int keepalive : 2;		/* Are we using HTTP Keep-Alive?
+                                 * -1 fatal error, 0 undecided, 1 yes */
+  int keptalive : 1;		/* Did we use HTTP Keep-Alive? */
+  int double_reverse : 2;	/* have we done double-reverse DNS?
+				 * -1 yes/failure, 0 not yet, 1 yes/success */
   int keepalives;		/* How many times have we used it? */
 };
 
Index: src/mod_access.c
===================================================================
RCS file: /export/home/cvs/apache/src/mod_access.c,v
retrieving revision 1.20
diff -u -r1.20 mod_access.c
--- mod_access.c	1997/07/27 01:43:21	1.20
+++ mod_access.c	1997/07/27 07:03:09
@@ -63,9 +63,24 @@
 #include "http_log.h"
 #include "http_request.h"
 
+enum allowdeny_type {
+    T_ENV,
+    T_ALL,
+    T_IP,
+    T_HOST,
+    T_FAIL
+};
+
 typedef struct {
-    char *from;
     int limited;
+    union {
+	char *from;
+	struct {
+	    unsigned long net;
+	    unsigned long mask;
+	} ip;
+    } x;
+    enum allowdeny_type type;
 } allowdeny;
 
 /* things in the 'order' array */
@@ -111,17 +126,104 @@
     return NULL;
 }
 
+static int is_ip(const char *host)
+{
+    while ((*host == '.') || isdigit(*host))
+        host++;
+    return (*host == '\0');
+}
+
 static const char *allow_cmd (cmd_parms *cmd, void *dv, char *from, char *where)
 {
     access_dir_conf *d = (access_dir_conf *)dv;
     allowdeny *a;
+    char *s;
   
     if (strcasecmp (from, "from"))
         return "allow and deny must be followed by 'from'";
     
     a = (allowdeny *)push_array (cmd->info ? d->allows : d->denys);
-    a->from = pstrdup (cmd->pool, where);
+    a->x.from = where = pstrdup (cmd->pool, where);
     a->limited = cmd->limited;
+    
+    if (!strncmp (where, "env=", 4)) {
+	a->type = T_ENV;
+	a->x.from += 4;
+
+    } else if (!strcmp (where, "all")) {
+	a->type = T_ALL;
+
+    } else if ((s = strchr (where, '/'))) {
+	unsigned long mask;
+
+	a->type = T_IP;
+	/* trample on where, we won't be using it any more */
+	*s++ = '\0';
+
+	if (!is_ip (where)
+	    || (a->x.ip.net = ap_inet_addr (where)) == INADDR_NONE) {
+	    a->type = T_FAIL;
+	    return "syntax error in network portion of network/netmask";
+	}
+
+	/* is_ip just tests if it matches [\d.]+ */
+	if (!is_ip (s)) {
+	    a->type = T_FAIL;
+	    return "syntax error in mask portion of network/netmask";
+	}
+	/* is it in /a.b.c.d form? */
+	if (strchr (s, '.')) {
+	    mask = ap_inet_addr (s);
+	    if (mask == INADDR_NONE) {
+		a->type = T_FAIL;
+		return "syntax error in mask portion of network/netmask";
+	    }
+	} else {
+	    /* assume it's in /nnn form */
+	    mask = atoi (s);
+	    if (mask > 32 || mask <= 0) {
+		a->type = T_FAIL;
+		return "invalid mask in network/netmask";
+	    }
+	    mask = 0xFFFFFFFFUL << (32 - mask);
+	    mask = htonl (mask);
+	}
+	a->x.ip.mask = mask;
+
+    } else if (isdigit (*where) && is_ip (where)) {
+	/* legacy syntax for ip addrs: a.b.c. ==> a.b.c.0/24 for example */
+	int shift;
+	char *t;
+
+	a->type = T_IP;
+	/* parse components */
+	s = where;
+	a->x.ip.net = 0;
+	shift = 0;
+	while (*s) {
+	    t = s;
+	    if (!isdigit (*t)) {
+		a->type = T_FAIL;
+		return "invalid ip address";
+	    }
+	    while (isdigit (*t)) {
+		++t;
+	    }
+	    if (*t == '.') {
+		*t++ = 0;
+	    } else if (*t) {
+		a->type = T_FAIL;
+		return "invalid ip address";
+	    }
+	    a->x.ip.net |= atoi(s) << shift;
+	    a->x.ip.mask |= 0xFFUL << shift;
+	    shift += 8;
+	    s = t;
+	}
+    } else {
+	a->type = T_HOST;
+    }
+
     return NULL;
 }
 
@@ -155,25 +257,6 @@
         return 0;
 }
 
-static int in_ip(char *domain, char *what) {
-
-    /* Check a similar screw case to the one checked above ---
-     * "allow from 204.26.2" shouldn't let in people from 204.26.23
-     */
-    
-    int l = strlen(domain);
-    if (strncmp(domain,what,l) != 0) return 0;
-    if (domain[l - 1] == '.') return 1;
-    return (what[l] == '\0' || what[l] == '.');
-}
-
-static int is_ip(const char *host)
-{
-    while ((*host == '.') || isdigit(*host))
-        host++;
-    return (*host == '\0');
-}
-
 static int find_allowdeny (request_rec *r, array_header *a, int method)
 {
     allowdeny *ap = (allowdeny *)a->elts;
@@ -186,39 +269,43 @@
         if (!(mmask & ap[i].limited))
 	    continue;
 
-	if (!strncmp(ap[i].from,"env=",4) && table_get(r->subprocess_env,ap[i].from+4))
+	switch (ap[i].type) {
+	case T_ENV:
+	    if (table_get (r->subprocess_env, ap[i].x.from)) {
+		return 1;
+	    }
+	    break;
+
+	case T_ALL:
 	    return 1;
-	    
-        if (ap[i].from && !strcmp(ap[i].from, "user-agents")) {
-	    char * this_agent = table_get(r->headers_in, "User-Agent");
-	    int j;
-  
-	    if (!this_agent) return 0;
-  
-	    for (j = i+1; j < a->nelts; ++j) {
-	        if (strstr(this_agent, ap[j].from)) return 1;
+
+	case T_IP:
+	    if (ap[i].x.ip.net != INADDR_NONE
+		&& (r->connection->remote_addr.sin_addr.s_addr
+		    & ap[i].x.ip.mask) == ap[i].x.ip.net) {
+		return 1;
 	    }
-	    return 0;
-	}
+	    break;
 	
-	if (!strcmp (ap[i].from, "all"))
-	    return 1;
+	case T_HOST:
+	    if (!gothost) {
+		remotehost = get_remote_host(r->connection, r->per_dir_config,
+					    REMOTE_DOUBLE_REV);
+
+		if ((remotehost == NULL) || is_ip(remotehost))
+		    gothost = 1;
+		else
+		    gothost = 2;
+	    }
 
-	if (!gothost) {
-	    remotehost = get_remote_host(r->connection, r->per_dir_config,
-	                                 REMOTE_HOST);
-
-	    if ((remotehost == NULL) || is_ip(remotehost))
-	        gothost = 1;
-	    else
-	        gothost = 2;
+	    if ((gothost == 2) && in_domain(ap[i].x.from, remotehost))
+		return 1;
+	    break;
+
+	case T_FAIL:
+	    /* do nothing? */
+	    break;
 	}
-
-        if ((gothost == 2) && in_domain(ap[i].from, remotehost))
-            return 1;
-
-        if (in_ip (ap[i].from, r->connection->remote_ip))
-            return 1;
     }
 
     return 0;


Re: [PATCH] mod_access overhaul (take 2)

Posted by Alexei Kosut <ak...@organic.com>.
On Sun, 27 Jul 1997, Dean Gaudet wrote:

> BTW it's surprising the number of tristate fields whose names or
> descriptions make them sound like booleans.  content_md5, do_rfc1413,
> keepalive, hostname_lookups (pre-this patch).

Well, they're only tristate in configuration; once the server starts
running, they are boolean. They use the third state (if I recall
correctly) to indicate an unset value, which allows virtual hosts to
inherit the main server's value, not the default.

So as far as what the fields contain to the server's perspective, they
are boolean...

-- Alexei Kosut <ak...@organic.com>