]> granicus.if.org Git - apache/commitdiff
Add ability to use multiple providers for basic and digest authentication.
authorJustin Erenkrantz <jerenkrantz@apache.org>
Wed, 18 Sep 2002 01:05:25 +0000 (01:05 +0000)
committerJustin Erenkrantz <jerenkrantz@apache.org>
Wed, 18 Sep 2002 01:05:25 +0000 (01:05 +0000)
The syntax is:

AuthBasicProvider file dbm
AuthUserFile conf/basic-user
AuthDBMUserFile conf/basic-user-dbm

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

modules/aaa/mod_auth.h
modules/aaa/mod_auth_basic.c
modules/aaa/mod_auth_digest.c

index f7fe064c1f455d4fe3b5a62d7428c05476778a0c..f0f4fbf4ccfc2bbd5c14643d568410718bd9a2af 100644 (file)
@@ -106,6 +106,15 @@ typedef struct {
                                    const char *realm, char **rethash);
 } authn_provider;
 
+/* A linked-list of authn providers. */
+typedef struct authn_provider_list authn_provider_list;
+
+struct authn_provider_list {
+    const char *provider_name;
+    const authn_provider *provider;
+    authn_provider_list *next;
+};
+
 AAA_DECLARE(void) authn_register_provider(apr_pool_t *p, const char *name,
                                          const authn_provider *provider);
 AAA_DECLARE(const authn_provider *) authn_lookup_provider(const char *name);
index 3f76418a360035eb2853e1edd6fb3ed2f0d7bdf7..c4b390ff87ee56f2c047396e14b3f285c5eb543e 100644 (file)
@@ -74,8 +74,7 @@
 #include "mod_auth.h"
 
 typedef struct {
-    const char *provider_name;
-    const authn_provider *provider;
+    authn_provider_list *providers;
     char *dir;
     int authoritative;
 } auth_basic_config_rec;
@@ -95,29 +94,46 @@ static const char *add_authn_provider(cmd_parms *cmd, void *config,
                                       const char *arg)
 {
     auth_basic_config_rec *conf = (auth_basic_config_rec*)config;
+    authn_provider_list *newp;
+    const char *provider_name;
 
     if (strcasecmp(arg, "on") == 0) {
-        conf->provider_name = AUTHN_DEFAULT_PROVIDER;
+        provider_name = AUTHN_DEFAULT_PROVIDER;
     }
     else if (strcasecmp(arg, "off") == 0) {
-        conf->provider_name = NULL;
-        conf->provider = NULL;
+        /* Clear all configured providers and return. */
+        conf->providers = NULL;
+        return NULL;
     }
     else {
-        conf->provider_name = apr_pstrdup(cmd->pool, arg);
+        provider_name = apr_pstrdup(cmd->pool, arg);
+    }
+
+    newp = apr_pcalloc(cmd->pool, sizeof(authn_provider_list));
+    newp->provider_name = provider_name;
+
+    /* lookup and cache the actual provider now */
+    newp->provider = authn_lookup_provider(newp->provider_name);
+
+    if (newp->provider == NULL) {
+        /* by the time they use it, the provider should be loaded and
+           registered with us. */
+        return apr_psprintf(cmd->pool,
+                            "Unknown Authn provider: %s",
+                            newp->provider_name);
     }
 
-    if (conf->provider_name != NULL) {
-        /* lookup and cache the actual provider now */
-        conf->provider = authn_lookup_provider(conf->provider_name);
+    /* Add it to the list now. */
+    if (!conf->providers) {
+        conf->providers = newp;
+    }
+    else {
+        authn_provider_list *last = conf->providers;
 
-        if (conf->provider == NULL) {
-            /* by the time they use it, the provider should be loaded and
-               registered with us. */
-            return apr_psprintf(cmd->pool,
-                                "Unknown Authn provider: %s",
-                                conf->provider_name);
+        while (last->next) {
+            last = last->next;
         }
+        last->next = newp;
     }
 
     return NULL;
@@ -207,6 +223,7 @@ static int authenticate_basic_user(request_rec *r)
     const char *sent_user, *sent_pw, *current_auth;
     int res;
     authn_status auth_result;
+    authn_provider_list *current_provider;
 
     /* Are we configured to be Basic auth? */
     current_auth = ap_auth_type(r);
@@ -228,15 +245,35 @@ static int authenticate_basic_user(request_rec *r)
         return res;
     }
 
-    /* For now, if a provider isn't set, we'll be nice and use the file
-     * provider.
-     */
-    if (!conf->provider) {
-        conf->provider = authn_lookup_provider(AUTHN_DEFAULT_PROVIDER);
-    }
+    current_provider = conf->providers;
+    do {
+        const authn_provider *provider;
 
-    auth_result = conf->provider->check_password(r, sent_user, sent_pw);
+        /* For now, if a provider isn't set, we'll be nice and use the file
+         * provider.
+         */
+        if (!current_provider) {
+            provider = authn_lookup_provider(AUTHN_DEFAULT_PROVIDER);
+        }
+        else {
+            provider = current_provider->provider;
+        }
+
+        auth_result = provider->check_password(r, sent_user, sent_pw);
+
+        /* Access is granted.  Stop checking. */
+        if (auth_result == AUTH_GRANTED) {
+            break;
+        }
+
+        /* If we're not really configured for providers, stop now. */
+        if (!conf->providers) {
+            break;
+        }
 
+        current_provider = current_provider->next;
+    } while (current_provider);
+    
     if (auth_result != AUTH_GRANTED) {
         int return_code;
 
index 4dbe89c5cebbad089020e4247156d31bb7d98bac..4058c93b4c13c19592bfd8b7327aa68bffef8b12 100644 (file)
 
 typedef struct digest_config_struct {
     const char  *dir_name;
-    const char *provider_name;
-    const authn_provider *provider;
+    authn_provider_list *providers;
     const char  *realm;
     char **qop_list;
     apr_sha1_ctx_t  nonce_ctx;
@@ -486,29 +485,46 @@ static const char *add_authn_provider(cmd_parms *cmd, void *config,
                                       const char *arg)
 {
     digest_config_rec *conf = (digest_config_rec*)config;
-
+    authn_provider_list *newp;
+    const char *provider_name;
+    
     if (strcasecmp(arg, "on") == 0) {
-        conf->provider_name = AUTHN_DEFAULT_PROVIDER;
+        provider_name = AUTHN_DEFAULT_PROVIDER;
     }
     else if (strcasecmp(arg, "off") == 0) {
-        conf->provider_name = NULL;
-        conf->provider = NULL;
+        /* Clear all configured providers and return. */
+        conf->providers = NULL; 
+        return NULL;
     }
     else {
-        conf->provider_name = apr_pstrdup(cmd->pool, arg);
+        provider_name = apr_pstrdup(cmd->pool, arg);
     }
 
-    if (conf->provider_name != NULL) {
-        /* lookup and cache the actual provider now */
-        conf->provider = authn_lookup_provider(conf->provider_name);
+    newp = apr_pcalloc(cmd->pool, sizeof(authn_provider_list));
+    newp->provider_name = provider_name;
+
+    /* lookup and cache the actual provider now */
+    newp->provider = authn_lookup_provider(newp->provider_name);
+
+    if (newp->provider == NULL) {
+       /* by the time they use it, the provider should be loaded and
+           registered with us. */
+        return apr_psprintf(cmd->pool,
+                            "Unknown Authn provider: %s",
+                            newp->provider_name);
+    }
 
-        if (conf->provider == NULL) {
-            /* by the time they use it, the provider should be loaded and
-               registered with us. */
-            return apr_psprintf(cmd->pool,
-                                "Unknown Authn provider: %s",
-                                conf->provider_name);
+    /* Add it to the list now. */
+    if (!conf->providers) {
+        conf->providers = newp;
+    }
+    else {
+        authn_provider_list *last = conf->providers;
+
+        while (last->next) {
+            last = last->next;
         }
+        last->next = newp;
     }
 
     return NULL;
@@ -1447,23 +1463,45 @@ static const char *get_hash(request_rec *r, const char *user,
 {
     authn_status auth_result;
     char *password;
+    authn_provider_list *current_provider;
 
-    /* To be nice, if we make it this far and we don't have a provider set,
-     * we'll use the default provider.
-     */
-    if (!conf->provider) {
-        conf->provider = authn_lookup_provider(AUTHN_DEFAULT_PROVIDER);
-    }
+    current_provider = conf->providers;
+    do {
+        const authn_provider *provider;
 
-    /* We expect the password to be md5 hash of user:realm:password */
-    auth_result = conf->provider->get_realm_hash(r, user, conf->realm,
-                                                 &password);
+        /* For now, if a provider isn't set, we'll be nice and use the file
+         * provider.
+         */
+        if (!current_provider) {
+            provider = authn_lookup_provider(AUTHN_DEFAULT_PROVIDER);
+        }
+        else {
+            provider = current_provider->provider;
+        }
+
+        /* We expect the password to be md5 hash of user:realm:password */
+        auth_result = provider->get_realm_hash(r, user, conf->realm,
+                                               &password);
+
+        /* User is found.  Stop checking. */
+        if (auth_result == AUTH_USER_FOUND) {
+            break;
+        }
+
+        /* If we're not really configured for providers, stop now. */
+        if (!conf->providers) {
+           break;
+        }
+
+        current_provider = current_provider->next;
+    } while (current_provider);
 
     if (auth_result != AUTH_USER_FOUND) {
         return NULL;
     }
-
-    return password;
+    else {
+        return password;
+    }
 }
 
 static int check_nc(const request_rec *r, const digest_header_rec *resp,
@@ -1822,10 +1860,6 @@ static int authenticate_digest_user(request_rec *r)
         return HTTP_UNAUTHORIZED;
     }
 
-    if (!conf->provider) {
-        return DECLINED;
-    }
-
     if (!(conf->ha1 = get_hash(r, r->user, conf))) {
         ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                       "Digest: user `%s' in realm `%s' not found: %s",