]> granicus.if.org Git - apache/commitdiff
mod_authz_host: add a new "forward-dns" authorization type
authorFabien Coelho <fabien@apache.org>
Thu, 10 Mar 2016 13:33:31 +0000 (13:33 +0000)
committerFabien Coelho <fabien@apache.org>
Thu, 10 Mar 2016 13:33:31 +0000 (13:33 +0000)
This new type does not rely on reverse DNS lookups.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1734412 13f79535-47bb-0310-9956-ffa450edef68

docs/log-message-tags/next-number
docs/manual/mod/mod_authz_host.xml
modules/aaa/mod_authz_host.c

index 1663343ca2a5d34861485e70741474046dec666d..13415bb98d5b29531a5d27eb51368c310a17ce1b 100644 (file)
@@ -1 +1 @@
-3354
+3357
index 665552c8ce7c9a6c6ab7d4c99f7abc5ccdd88a54..27e29cb2f60f94259d2008e8f858d7d94921849b 100644 (file)
@@ -58,7 +58,8 @@ address)</description>
     <p>Apache's <directive module="mod_authz_core">Require</directive>
     directive is used during the authorization phase to ensure that a user is allowed or
     denied access to a resource.  mod_authz_host extends the
-    authorization types with <code>ip</code>, <code>host</code> and <code>local</code>.
+    authorization types with <code>ip</code>, <code>host</code>,
+    <code>forward-dns</code> and <code>local</code>.
     Other authorization types may also be
     used but may require that additional authorization modules be loaded.</p>
 
@@ -157,6 +158,29 @@ Require host .net example.edu
 
 </section>
 
+<section id="reqfwddns"><title>Require forward-dns</title>
+
+    <p>The <code>forward-dns</code> provider allows access to the server
+    to be controlled based on simple host names.  When
+    <code>Require forward-dns <var>host-name</var></code> is specified,
+    all IP addresses corresponding to <code><var>host-name</var></code>
+    are allowed access.</p>
+
+    <p>In contrast to the <code>host</code> provider, this provider does not
+    rely on reverse DNS lookups: it simply queries the DNS for the host name
+    and allows a client if its IP matches.  As a consequence, it will only
+    work with host names, not domain names.  However, as the reverse DNS is
+    not used, it will work with clients which use a dynamic DNS service.</p>
+
+    <highlight language="config">
+Require forward-dns bla.example.org
+    </highlight>
+
+    <p>A client the IP of which is resolved from the name
+    <code>bla.example.org</code> will be granted access.</p>
+
+</section>
+
 <section id="reqlocal"><title>Require local</title>
 
     <p>The <code>local</code> provider allows access to the server if any
index 15f453996e02c24af53920ff4706ce573b91e106..2236b65ceae2a45c2bb54cd04dbe2251db16bad8 100644 (file)
@@ -216,6 +216,71 @@ static authz_status host_check_authorization(request_rec *r,
     return AUTHZ_DENIED;
 }
 
+static authz_status
+forward_dns_check_authorization(request_rec *r,
+                                const char *require_line,
+                                const void *parsed_require_line)
+{
+    const char *err = NULL;
+    const ap_expr_info_t *expr = parsed_require_line;
+    const char *require, *t;
+    char *w;
+
+    /* the require line is an expression, which is evaluated now. */
+    require = ap_expr_str_exec(r, expr, &err);
+    if (err) {
+      ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(03354)
+                    "Can't evaluate require expression: %s", err);
+      return AUTHZ_DENIED;
+    }
+
+    /* tokenize expected list of names */
+    t = require;
+    while ((w = ap_getword_conf(r->pool, &t)) && w[0]) {
+
+        apr_sockaddr_t *sa;
+        apr_status_t rv;
+        char *hash_ptr;
+
+        /* stop on apache configuration file comments */
+        if ((hash_ptr = ap_strchr(w, '#'))) {
+            if (hash_ptr == w) {
+                break;
+            }
+            *hash_ptr = '\0';
+        }
+
+        /* does the client ip match one of the names? */
+        rv = apr_sockaddr_info_get(&sa, w, APR_UNSPEC, 0, 0, r->pool);
+        if (rv == APR_SUCCESS) {
+
+            while (sa) {
+                int match = apr_sockaddr_equal(sa, r->useragent_addr);
+
+                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03355)
+                              "access check for %s as '%s': %s",
+                              r->useragent_ip, w, match? "yes": "no");
+                if (match) {
+                    return AUTHZ_GRANTED;
+                }
+
+                sa = sa->next;
+            }
+        }
+        else {
+            ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(03356)
+                          "No sockaddr info for \"%s\"", w);
+        }
+
+        /* stop processing, we are in a comment */
+        if (hash_ptr) {
+            break;
+        }
+    }
+
+    return AUTHZ_DENIED;
+}
+
 static authz_status local_check_authorization(request_rec *r,
                                               const char *require_line,
                                               const void *parsed_require_line)
@@ -265,6 +330,12 @@ static const authz_provider authz_host_provider =
     &host_parse_config,
 };
 
+static const authz_provider authz_forward_dns_provider =
+{
+    &forward_dns_check_authorization,
+    &host_parse_config,
+};
+
 static const authz_provider authz_local_provider =
 {
     &local_check_authorization,
@@ -309,6 +380,10 @@ static void register_hooks(apr_pool_t *p)
     ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "host",
                               AUTHZ_PROVIDER_VERSION,
                               &authz_host_provider, AP_AUTH_INTERNAL_PER_CONF);
+    ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "forward-dns",
+                              AUTHZ_PROVIDER_VERSION,
+                              &authz_forward_dns_provider,
+                              AP_AUTH_INTERNAL_PER_CONF);
     ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "local",
                               AUTHZ_PROVIDER_VERSION,
                               &authz_local_provider, AP_AUTH_INTERNAL_PER_CONF);