]> granicus.if.org Git - apache-authnz-external/commitdiff
Modified AuthExternal directive to be able to take more than one authenticator name.
authorjan@unixpapa.com <jan@unixpapa.com@8c465660-3f02-11de-a81c-fde7d73ceb89>
Fri, 15 May 2009 15:04:56 +0000 (15:04 +0000)
committerjan@unixpapa.com <jan@unixpapa.com@8c465660-3f02-11de-a81c-fde7d73ceb89>
Fri, 15 May 2009 15:04:56 +0000 (15:04 +0000)
mod_authnz_external/CHANGES
mod_authnz_external/INSTALL
mod_authnz_external/README
mod_authnz_external/mod_authnz_external.c

index 7c789965dd6b484cc89673e976a1ae09dc027133..ca2b2c50a9a1ae5f4dc265da6f175f747106df0a 100644 (file)
@@ -1,3 +1,11 @@
+v3.2.4   (Jan Wolter - May 15, 2009)
+-----------------------------------------------
+ * Modified AuthExternal directive to be able to take more than one
+   authenticator name.  If more than one is defined, then each authenticator
+   is run in turn, until one succeeds or all have failed.  Probably a similar
+   change should be made to GroupExternal, but it hasn't been done yet because
+   it's a more complex change and nobody has asked for it.
+
 v3.2.3   (Jan Wolter - Feb 26, 2009)
 -----------------------------------------------
  * Added GroupExternalError directive, which allows you to specify the
index 5f93d283abb05ee6d1323ef1ed9faabe770adec0..9201510e4cd2f0b585df040dc0adac7f00d122aa 100644 (file)
@@ -402,7 +402,7 @@ instructions to your server configuration.
        Require valid-user
 
     Here <authname> identifies what we are authenticating for - it usually
-    appears in the browser's pop-up login windown.  <keyword> matches a
+    appears in the browser's pop-up login window.  <keyword> matches a
     keyword you defined with DefineExternalAuth or AddExternalAuth in step 2.
 
     If you only want some users to have access to the directory, as opposed
@@ -417,6 +417,16 @@ instructions to your server configuration.
 
        Require file-owner
 
+    It is possible to list more than one authenticator on the AuthExternal
+    command:
+
+        AuthExternal <keyword1> <keyword2>...
+
+    Here each keyword should match an authenticator defined with the
+    DefineExternalAuth command.  If the first authenticator fails, then
+    the second one will be run, and so on, until either one authenticator
+    accepts the user's login/password combination or all reject it.
+
     * EXTERNAL GROUP CHECKING:
 
     If you want to use the external group check program to allow only
@@ -449,6 +459,9 @@ instructions to your server configuration.
 
         Require file-group
 
+    The GroupExternal cannot (yet?) be used with multiple external
+    authenticators.
+
     * PASSING CONTEXT INFORMATION INTO AUTHENTICATORS:
 
     If you want the authentication to work slightly differently in
@@ -551,7 +564,7 @@ instructions to your server configuration.
 
       - Miscellaneous odd behaviors.
 
-       Did you restart the httpd after the last time you editted the
+       Did you restart the httpd after the last time you edited the
        httpd.conf file or recompiled Apache?  Confirm that an
        "Apache configured -- resuming normal operations" message appeared
        in the error log when you restarted.
index fd4a53aaebaf5a570400b4dc7f2c12336511df7e..345626cb8984fc80281e6a1a6fa8076f4fb32e3c 100644 (file)
@@ -1,4 +1,4 @@
-                   Mod_Authnz_External version 3.2.3
+                   Mod_Authnz_External version 3.2.4
 
      Original Coder: Nathan Neulinger <nneul@umr.edu>
 Previous Maintainer: Tyler Allison    <allison@nas.nasa.gov>
index 2129ea9d4f4ca3618a8c08e99d4b00eb0df0b1ba..867ee4f3ee5f02afa484cdf924be3de4cfa1d658 100644 (file)
@@ -115,7 +115,7 @@ module AP_MODULE_DECLARE_DATA authnz_external_module;
 
 typedef struct
 {
-    char *auth_name;            /* Auth keyword for current dir */
+    apr_array_header_t *auth_name; /* Auth keyword for current dir */
     char *group_name;           /* Group keyword for current dir */
     char *context;              /* Context string from AuthExternalContext */
     int  authoritative;                 /* Are we authoritative in current dir? */
@@ -148,7 +148,7 @@ static void *create_authnz_external_dir_config(apr_pool_t *p, char *d)
     authnz_external_dir_config_rec *dir= (authnz_external_dir_config_rec *)
        apr_palloc(p, sizeof(authnz_external_dir_config_rec));
 
-    dir->auth_name= NULL;      /* no default */
+    dir->auth_name= apr_array_make(p,2,sizeof(const char *));  /* no default */
     dir->group_name= NULL;     /* no default */
     dir->context= NULL;                /* no default */
     dir->authoritative= 1;     /* strong by default */
@@ -281,6 +281,19 @@ static const char *set_extgroup_method(cmd_parms *cmd, void *dummy,
     return NULL;
 }
 
+/* Append an argument to an array defined by the offset */
+static const char *append_array_slot(cmd_parms *cmd, void *struct_ptr,
+                               const char *arg)
+{
+    int offset = (int)(long)cmd->info;
+    apr_array_header_t *array=
+       *(apr_array_header_t **)((char *)struct_ptr + offset);
+
+    *(const char **)apr_array_push(array)= apr_pstrdup(array->pool, arg);
+
+    return NULL;
+}
+
 
 /*
  * Config file commands that this module can handle
@@ -288,11 +301,11 @@ static const char *set_extgroup_method(cmd_parms *cmd, void *dummy,
 
 static const command_rec authnz_external_cmds[] =
 {
-    AP_INIT_TAKE1("AuthExternal",
-       ap_set_string_slot,
+    AP_INIT_ITERATE("AuthExternal",
+       append_array_slot,
        (void *)APR_OFFSETOF(authnz_external_dir_config_rec,auth_name),
        OR_AUTHCFG,
-       "a keyword indicating which authenticator to use"),
+       "one (or more) keywords indicating which authenticators to use"),
 
     AP_INIT_TAKE3("DefineExternalAuth",
        def_extauth,
@@ -722,47 +735,53 @@ static int authz_external_check_user_access(request_rec *r)
 static authn_status authn_external_check_password(request_rec *r,
        const char *user, const char *password)
 {
-    const char *extpath, *extmethod;
+    const char *extname, *extpath, *extmethod;
+    int i;
     authnz_external_dir_config_rec *dir= (authnz_external_dir_config_rec *)
            ap_get_module_config(r->per_dir_config, &authnz_external_module);
 
     authnz_external_svr_config_rec *svr= (authnz_external_svr_config_rec *)
            ap_get_module_config(r->server->module_config,
                &authnz_external_module);
-    const char *extname= dir->auth_name;
     int code= 1;
 
     /* Check if we are supposed to handle this authentication */
-    if ( extname == NULL )
+    if (dir->auth_name->nelts == 0)
     {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
            "No AuthExternal name has been set");
        return AUTH_GENERAL_ERROR;
     }
 
-    /* Get the path associated with that external */
-    if (!(extpath= apr_table_get(svr->auth_path, extname)))
+    for (i= 0; i < dir->auth_name->nelts; i++)
     {
-       ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
-           "Invalid AuthExternal keyword (%s)", extname);
-       return AUTH_GENERAL_ERROR;
-    }
+       extname= ((const char **)dir->auth_name->elts)[i];
 
-    /* Do the authentication, by the requested method */
-    extmethod= apr_table_get(svr->auth_method, extname);
-    if ( extmethod && !strcasecmp(extmethod, "function") )
-       code= exec_hardcode(r, extpath, password);
-    else
-       code= exec_external(extpath, extmethod, r, ENV_PASS, password);
+       /* Get the path associated with that external */
+       if (!(extpath= apr_table_get(svr->auth_path, extname)))
+       {
+           ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+               "Invalid AuthExternal keyword (%s)", extname);
+           return AUTH_GENERAL_ERROR;
+       }
 
-    /* If return code was zero, authentication succeeded */
-    if (code == 0) return AUTH_GRANTED;
+       /* Do the authentication, by the requested method */
+       extmethod= apr_table_get(svr->auth_method, extname);
+       if ( extmethod && !strcasecmp(extmethod, "function") )
+           code= exec_hardcode(r, extpath, password);
+       else
+           code= exec_external(extpath, extmethod, r, ENV_PASS, password);
 
-    /* Otherwise it failed */
-    errno= 0;
-    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
-       "AuthExtern %s [%s]: Failed (%d) for user %s",
-       extname, extpath, code, r->user);
+       /* If return code was zero, authentication succeeded */
+       if (code == 0) return AUTH_GRANTED;
+
+       /* Log a failed authentication */
+       errno= 0;
+       ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+           "AuthExtern %s [%s]: Failed (%d) for user %s",
+           extname, extpath, code, r->user);
+    }
+    /* If no authenticators succeed, refuse authentication */
     return AUTH_DENIED;
 }