You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by je...@apache.org on 2002/09/10 02:15:40 UTC

cvs commit: httpd-2.0/modules/aaa mod_auth_basic.c mod_authn_anon.c mod_authn_dbm.c mod_authn_default.c mod_authn_file.c mod_authz_dbm.c mod_authz_default.c mod_authz_groupfile.c mod_authz_host.c mod_authz_user.c config.m4 mod_auth_digest.c NWGNUauthanon NWGNUauthdbm mod_access.c mod_access.dsp mod_access.exp mod_auth.c mod_auth.dsp mod_auth.exp mod_auth_anon.c mod_auth_anon.dsp mod_auth_anon.exp mod_auth_dbm.c mod_auth_dbm.dsp mod_auth_dbm.exp

jerenkrantz    2002/09/09 17:15:40

  Modified:    .        CHANGES
               modules/aaa config.m4 mod_auth_digest.c
  Added:       modules/aaa mod_auth_basic.c mod_authn_anon.c
                        mod_authn_dbm.c mod_authn_default.c
                        mod_authn_file.c mod_authz_dbm.c
                        mod_authz_default.c mod_authz_groupfile.c
                        mod_authz_host.c mod_authz_user.c
  Removed:     modules/aaa NWGNUauthanon NWGNUauthdbm mod_access.c
                        mod_access.dsp mod_access.exp mod_auth.c
                        mod_auth.dsp mod_auth.exp mod_auth_anon.c
                        mod_auth_anon.dsp mod_auth_anon.exp mod_auth_dbm.c
                        mod_auth_dbm.dsp mod_auth_dbm.exp
  Log:
  Stage #1 of the aaa rewrite - refactoring modules.
  
  All modules are reorganized under the following scheme:
  - mod_auth_*:   Front-end (basic, digest)
  - mod_authn_*:  Authentication (anon, dbm, default, file)
  - mod_authz_*:  Authorization (dbm, default, groupfile, host, user)
  
  This passes the httpd-test suite when it accounts for the renaming of
  aaa modules.
  
  Originally written by: Dirk-Willem van Gulik
  Completed by: Justin Erenkrantz
  
  Revision  Changes    Path
  1.919     +3 -0      httpd-2.0/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/CHANGES,v
  retrieving revision 1.918
  retrieving revision 1.919
  diff -u -u -r1.918 -r1.919
  --- CHANGES	9 Sep 2002 21:37:56 -0000	1.918
  +++ CHANGES	10 Sep 2002 00:15:39 -0000	1.919
  @@ -1,5 +1,8 @@
   Changes with Apache 2.0.41
   
  +  *) Rewrite of aaa modules to an authn/authz model.
  +     [Dirk-Willem van Gulik, Justin Erenkrantz]
  +  
     *) Update OpenSSL detection to work on Darwin.
        [Sander Temme <sc...@covalent.net>]
   
  
  
  
  1.55      +32 -9     httpd-2.0/modules/aaa/config.m4
  
  Index: config.m4
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/modules/aaa/config.m4,v
  retrieving revision 1.54
  retrieving revision 1.55
  diff -u -u -r1.54 -r1.55
  --- config.m4	5 Feb 2002 22:41:18 -0000	1.54
  +++ config.m4	10 Sep 2002 00:15:39 -0000	1.55
  @@ -1,22 +1,45 @@
   dnl modules enabled in this directory by default
   
  +dnl Authentication (authn), Access, and Authorization (authz)
  +
   dnl APACHE_MODULE(name, helptext[, objects[, structname[, default[, config]]]])
   
   APACHE_MODPATH_INIT(aaa)
   
  -APACHE_MODULE(access, host-based access control, , , yes)
  -APACHE_MODULE(auth, user-based access control, , , yes)
  -APACHE_MODULE(auth_anon, anonymous user access, , , most)
  -APACHE_MODULE(auth_dbm, DBM-based access databases, , , most)
  +dnl Authentication modules; modules checking a username and password against a
  +dnl file, database, or other similar magic.
  +dnl
  +APACHE_MODULE(authn_file, file-based authentication control, , , yes)
  +APACHE_MODULE(authn_dbm, DBM-based authentication control, , , most)
  +APACHE_MODULE(authn_anon, anonymous user authentication control, , , most)
  +
  +dnl - and just in case all of the above punt; a default handler to
  +dnl keep the bad guys out.
  +APACHE_MODULE(authn_default, authentication backstopper, , , yes)
  +
  +dnl Authorization modules: modules which verify a certain property such as
  +dnl membership of a group, value of the IP address against a list of pre
  +dnl configured directives (e.g. require, allow) or against an external file
  +dnl or database.
  +dnl
  +APACHE_MODULE(authz_host, host-based authorization control, , , yes)
  +APACHE_MODULE(authz_groupfile, 'require group' authorization control, , , yes)
  +APACHE_MODULE(authz_user, 'require user' authorization control, , , yes)
  +APACHE_MODULE(authz_dbm, DBM-based authorization control, , , most)
  +
  +dnl - and just in case all of the above punt; a default handler to
  +dnl keep the bad guys out.
  +APACHE_MODULE(authz_default, authorization control backstopper, , , yes)
   
  +dnl these are the front-end authentication modules
  +APACHE_MODULE(auth_basic, basic authentication, , , yes)
   APACHE_MODULE(auth_digest, RFC2617 Digest authentication, , , most, [
     ap_old_cppflags=$CPPFLAGS
     CPPFLAGS="$CPPFLAGS -I$APR_SOURCE_DIR/include -I$abs_builddir/srclib/apr/include"
  -  AC_TRY_COMPILE([#include <apr.h>], 
  -                 [#if !APR_HAS_RANDOM 
  -                  #error You need APR random support to use auth_digest. 
  -                  #endif],,
  -                 enable_auth_digest=no)
  +  AC_TRY_COMPILE([#include <apr.h>], [
  +#if !APR_HAS_RANDOM 
  +#error You need APR random support to use mod_auth_digest. 
  +#endif], , enable_auth_digest=no)
     CPPFLAGS=$ap_old_cppflags
   ])
   
  
  
  
  1.69      +1 -151    httpd-2.0/modules/aaa/mod_auth_digest.c
  
  Index: mod_auth_digest.c
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/modules/aaa/mod_auth_digest.c,v
  retrieving revision 1.68
  retrieving revision 1.69
  diff -u -u -r1.68 -r1.69
  --- mod_auth_digest.c	10 Jul 2002 06:01:09 -0000	1.68
  +++ mod_auth_digest.c	10 Sep 2002 00:15:39 -0000	1.69
  @@ -130,7 +130,6 @@
   typedef struct digest_config_struct {
       const char  *dir_name;
       const char  *pwfile;
  -    const char  *grpfile;
       const char  *realm;
       char **qop_list;
       apr_sha1_ctx_t  nonce_ctx;
  @@ -487,13 +486,6 @@
       return NULL;
   }
   
  -static const char *set_group_file(cmd_parms *cmd, void *config,
  -                                  const char *file)
  -{
  -    ((digest_config_rec *) config)->grpfile = file;
  -    return NULL;
  -}
  -
   static const char *set_qop(cmd_parms *cmd, void *config, const char *op)
   {
       digest_config_rec *conf = (digest_config_rec *) config;
  @@ -645,8 +637,6 @@
        "The authentication realm (e.g. \"Members Only\")"),
       AP_INIT_TAKE1("AuthDigestFile", set_digest_file, NULL, OR_AUTHCFG, 
        "The name of the file containing the usernames and password hashes"),
  -    AP_INIT_TAKE1("AuthDigestGroupFile", set_group_file, NULL, OR_AUTHCFG, 
  -     "The name of the file containing the group names and members"),
       AP_INIT_ITERATE("AuthDigestQop", set_qop, NULL, OR_AUTHCFG, 
        "A list of quality-of-protection options"),
       AP_INIT_TAKE1("AuthDigestNonceLifetime", set_nonce_lifetime, NULL, OR_AUTHCFG, 
  @@ -1882,146 +1872,6 @@
       return OK;
   }
   
  -
  -/*
  - * Checking ID
  - */
  -
  -static apr_table_t *groups_for_user(request_rec *r, const char *user,
  -                                    const char *grpfile)
  -{
  -    ap_configfile_t *f;
  -    apr_table_t *grps = apr_table_make(r->pool, 15);
  -    apr_pool_t *sp;
  -    char l[MAX_STRING_LEN];
  -    const char *group_name, *ll, *w;
  -    apr_status_t sts;
  -
  -    if ((sts = ap_pcfg_openfile(&f, r->pool, grpfile)) != APR_SUCCESS) {
  -        ap_log_rerror(APLOG_MARK, APLOG_ERR, sts, r,
  -                      "Digest: Could not open group file: %s", grpfile);
  -        return NULL;
  -    }
  -
  -    if (apr_pool_create(&sp, r->pool) != APR_SUCCESS) {
  -        return NULL;
  -    }
  -
  -    while (!(ap_cfg_getline(l, MAX_STRING_LEN, f))) {
  -        if ((l[0] == '#') || (!l[0])) {
  -            continue;
  -        }
  -        ll = l;
  -        apr_pool_clear(sp);
  -
  -        group_name = ap_getword(sp, &ll, ':');
  -
  -        while (ll[0]) {
  -            w = ap_getword_conf(sp, &ll);
  -            if (!strcmp(w, user)) {
  -                apr_table_setn(grps, apr_pstrdup(r->pool, group_name), "in");
  -                break;
  -            }
  -        }
  -    }
  -
  -    ap_cfg_closefile(f);
  -    apr_pool_destroy(sp);
  -    return grps;
  -}
  -
  -
  -static int digest_check_auth(request_rec *r)
  -{
  -    const digest_config_rec *conf =
  -                (digest_config_rec *) ap_get_module_config(r->per_dir_config,
  -                                                           &auth_digest_module);
  -    const char *user = r->user;
  -    int m = r->method_number;
  -    int method_restricted = 0;
  -    register int x;
  -    const char *t, *w;
  -    apr_table_t *grpstatus;
  -    const apr_array_header_t *reqs_arr;
  -    require_line *reqs;
  -
  -    if (!(t = ap_auth_type(r)) || strcasecmp(t, "Digest")) {
  -        return DECLINED;
  -    }
  -
  -    reqs_arr = ap_requires(r);
  -    /* If there is no "requires" directive, then any user will do.
  -     */
  -    if (!reqs_arr) {
  -        return OK;
  -    }
  -    reqs = (require_line *) reqs_arr->elts;
  -
  -    if (conf->grpfile) {
  -        grpstatus = groups_for_user(r, user, conf->grpfile);
  -    }
  -    else {
  -        grpstatus = NULL;
  -    }
  -
  -    for (x = 0; x < reqs_arr->nelts; x++) {
  -
  -        if (!(reqs[x].method_mask & (AP_METHOD_BIT << m))) {
  -            continue;
  -        }
  -
  -        method_restricted = 1;
  -
  -        t = reqs[x].requirement;
  -        w = ap_getword_white(r->pool, &t);
  -        if (!strcasecmp(w, "valid-user")) {
  -            return OK;
  -        }
  -        else if (!strcasecmp(w, "user")) {
  -            while (t[0]) {
  -                w = ap_getword_conf(r->pool, &t);
  -                if (!strcmp(user, w)) {
  -                    return OK;
  -                }
  -            }
  -        }
  -        else if (!strcasecmp(w, "group")) {
  -            if (!grpstatus) {
  -                return DECLINED;
  -            }
  -
  -            while (t[0]) {
  -                w = ap_getword_conf(r->pool, &t);
  -                if (apr_table_get(grpstatus, w)) {
  -                    return OK;
  -                }
  -            }
  -        }
  -        else {
  -            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
  -                          "Digest: access to %s failed, reason: unknown "
  -                          "require directive \"%s\"",
  -                          r->uri, reqs[x].requirement);
  -            return DECLINED;
  -        }
  -    }
  -
  -    if (!method_restricted) {
  -        return OK;
  -    }
  -
  -    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
  -                  "Digest: access to %s failed, reason: user %s not "
  -                  "allowed access", r->uri, user);
  -
  -    note_digest_auth_failure(r, conf,
  -        (digest_header_rec *) ap_get_module_config(r->request_config,
  -                                                   &auth_digest_module),
  -        0);
  -    return HTTP_UNAUTHORIZED;
  -}
  -
  -
   /*
    * Authorization-Info header code
    */
  @@ -2207,7 +2057,7 @@
       ap_hook_child_init(initialize_child, NULL, NULL, APR_HOOK_MIDDLE);
       ap_hook_post_read_request(parse_hdr_and_update_nc, parsePre, NULL, APR_HOOK_MIDDLE);
       ap_hook_check_user_id(authenticate_digest_user, NULL, NULL, APR_HOOK_MIDDLE);
  -    ap_hook_auth_checker(digest_check_auth, NULL, NULL, APR_HOOK_MIDDLE);
  +
       ap_hook_fixups(add_auth_info, NULL, NULL, APR_HOOK_MIDDLE);
   }
   
  
  
  
  1.1                  httpd-2.0/modules/aaa/mod_auth_basic.c
  
  Index: mod_auth_basic.c
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * Portions of this software are based upon public domain software
   * originally written at the National Center for Supercomputing Applications,
   * University of Illinois, Urbana-Champaign.
   */
  
  /*
   * http_auth: authentication
   * 
   * Rob McCool
   * 
   * Adapted to Apache by rst.
   *
   * dirkx - Added Authoritative control to allow passing on to lower
   *         modules if and only if the userid is not known to this
   *         module. A known user with a faulty or absent password still
   *         causes an AuthRequired. The default is 'Authoritative', i.e.
   *         no control is passed along.
   */
  
  #include "apr_strings.h"
  #include "apr_md5.h"            /* for apr_password_validate */
  
  #include "ap_config.h"
  #include "httpd.h"
  #include "http_config.h"
  #include "http_core.h"
  #include "http_log.h"
  #include "http_protocol.h"
  #include "http_request.h"
  
  
  typedef struct {
      char *auth_pwfile;
      char *auth_grpfile;
      int authoritative;
  } auth_config_rec;
  
  static void *create_auth_dir_config(apr_pool_t *p, char *d)
  {
      auth_config_rec *conf = apr_palloc(p, sizeof(*conf));
  
      conf->auth_pwfile = NULL;     /* just to illustrate the default really */
      conf->auth_grpfile = NULL;    /* unless you have a broken HP cc */
      conf->authoritative = 1; /* keep the fortress secure by default */
      return conf;
  }
  
  static const char *set_auth_slot(cmd_parms *cmd, void *offset, const char *f, 
                                   const char *t)
  {
      if (t && strcmp(t, "standard")) {
          return apr_pstrcat(cmd->pool, "Invalid auth file type: ", t, NULL);
      }
  
      return ap_set_file_slot(cmd, offset, f);
  }
  
  static const command_rec auth_basic_cmds[] =
  {
      AP_INIT_TAKE12("AuthUserFile", set_auth_slot,
                     (void *)APR_OFFSETOF(auth_config_rec, auth_pwfile),
                     OR_AUTHCFG, "text file containing user IDs and passwords"),
      AP_INIT_TAKE12("AuthGroupFile", set_auth_slot,
                     (void *)APR_OFFSETOF(auth_config_rec, auth_grpfile),
                     OR_AUTHCFG,
                     "text file containing group names and member user IDs"),
      AP_INIT_FLAG("AuthAuthoritative", ap_set_flag_slot,
                   (void *)APR_OFFSETOF(auth_config_rec, authoritative),
                   OR_AUTHCFG,
                   "Set to 'no' to allow access control to be passed along to "
                   "lower modules if the UserID is not known to this module"),
      {NULL}
  };
  
  module AP_MODULE_DECLARE_DATA auth_basic_module;
  
  static char *get_pw(request_rec *r, char *user, char *auth_pwfile)
  {
      ap_configfile_t *f;
      char l[MAX_STRING_LEN];
      const char *rpw, *w;
      apr_status_t status;
  
      if ((status = ap_pcfg_openfile(&f, r->pool, auth_pwfile)) != APR_SUCCESS) {
          ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r,
                        "Could not open password file: %s", auth_pwfile);
          return NULL;
      }
      while (!(ap_cfg_getline(l, MAX_STRING_LEN, f))) {
          if ((l[0] == '#') || (!l[0])) {
              continue;
          }
          rpw = l;
          w = ap_getword(r->pool, &rpw, ':');
  
          if (!strcmp(user, w)) {
              ap_cfg_closefile(f);
              return ap_getword(r->pool, &rpw, ':');
          }
      }
      ap_cfg_closefile(f);
      return NULL;
  }
  
  static apr_table_t *groups_for_user(apr_pool_t *p, char *user, char *grpfile)
  {
      ap_configfile_t *f;
      apr_table_t *grps = apr_table_make(p, 15);
      apr_pool_t *sp;
      char l[MAX_STRING_LEN];
      const char *group_name, *ll, *w;
      apr_status_t status;
  
      if ((status = ap_pcfg_openfile(&f, p, grpfile)) != APR_SUCCESS) {
  /*add?  aplog_error(APLOG_MARK, APLOG_ERR, NULL,
                      "Could not open group file: %s", grpfile);*/
          return NULL;
      }
  
      apr_pool_create(&sp, p);
  
      while (!(ap_cfg_getline(l, MAX_STRING_LEN, f))) {
          if ((l[0] == '#') || (!l[0])) {
              continue;
          }
          ll = l;
          apr_pool_clear(sp);
  
          group_name = ap_getword(sp, &ll, ':');
  
          while (ll[0]) {
              w = ap_getword_conf(sp, &ll);
              if (!strcmp(w, user)) {
                  apr_table_setn(grps, apr_pstrdup(p, group_name), "in");
                  break;
              }
          }
      }
      ap_cfg_closefile(f);
      apr_pool_destroy(sp);
      return grps;
  }
  
  /* These functions return 0 if client is OK, and proper error status
   * if not... either HTTP_UNAUTHORIZED, if we made a check, and it failed, or
   * HTTP_INTERNAL_SERVER_ERROR, if things are so totally confused that we
   * couldn't figure out how to tell if the client is authorized or not.
   *
   * If they return DECLINED, and all other modules also decline, that's
   * treated by the server core as a configuration error, logged and
   * reported as such.
   */
  
  /* Determine user ID, and check if it really is that user, for HTTP
   * basic authentication...
   */
  
  static int authenticate_basic_user(request_rec *r)
  {
      auth_config_rec *conf = ap_get_module_config(r->per_dir_config,
                                                   &auth_basic_module);
      const char *sent_pw;
      char *real_pw;
      apr_status_t invalid_pw;
      int res;
  
      if ((res = ap_get_basic_auth_pw(r, &sent_pw))) {
          return res;
      }
  
      if (!conf->auth_pwfile) {
          return DECLINED;
      }
  
      if (!(real_pw = get_pw(r, r->user, conf->auth_pwfile))) {
          if (!conf->authoritative) {
              return DECLINED;
          }
          ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                        "user %s not found: %s", r->user, r->uri);
          ap_note_basic_auth_failure(r);
          return HTTP_UNAUTHORIZED;
      }
      invalid_pw = apr_password_validate(sent_pw, real_pw);
      if (invalid_pw != APR_SUCCESS) {
          ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                        "user %s: authentication failure for \"%s\": "
                        "Password Mismatch",
                        r->user, r->uri);
          ap_note_basic_auth_failure(r);
          return HTTP_UNAUTHORIZED;
      }
      return OK;
  }
  
  /* Checking ID */
  
  static int check_user_access(request_rec *r)
  {
      auth_config_rec *conf = ap_get_module_config(r->per_dir_config,
                                                   &auth_basic_module);
      char *user = r->user;
      int m = r->method_number;
      int method_restricted = 0;
      register int x;
      const char *t, *w;
      apr_table_t *grpstatus;
      const apr_array_header_t *reqs_arr = ap_requires(r);
      require_line *reqs;
  
      /* BUG FIX: tadc, 11-Nov-1995.  If there is no "requires" directive, 
       * then any user will do.
       */
      if (!reqs_arr) {
          return OK;
      }
      reqs = (require_line *)reqs_arr->elts;
  
      if (conf->auth_grpfile) {
          grpstatus = groups_for_user(r->pool, user, conf->auth_grpfile);
      }
      else {
          grpstatus = NULL;
      }
  
      for (x = 0; x < reqs_arr->nelts; x++) {
  
          if (!(reqs[x].method_mask & (AP_METHOD_BIT << m))) {
              continue;
          }
  
          method_restricted = 1;
  
          t = reqs[x].requirement;
          w = ap_getword_white(r->pool, &t);
          if (!strcmp(w, "valid-user")) {
              return OK;
          }
          if (!strcmp(w, "user")) {
              while (t[0]) {
                  w = ap_getword_conf(r->pool, &t);
                  if (!strcmp(user, w)) {
                      return OK;
                  }
              }
          }
          else if (!strcmp(w, "group")) {
              if (!grpstatus) {
                  return DECLINED;        /* DBM group?  Something else? */
              }
  
              while (t[0]) {
                  w = ap_getword_conf(r->pool, &t);
                  if (apr_table_get(grpstatus, w)) {
                      return OK;
                  }
              }
          }
          else if (conf->authoritative) {
              /* if we aren't authoritative, any require directive could be
               * valid even if we don't grok it.  However, if we are 
               * authoritative, we can warn the user they did something wrong.
               * That something could be a missing "AuthAuthoritative off", but
               * more likely is a typo in the require directive.
               */
              ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                            "access to %s failed, reason: unknown require "
                            "directive:\"%s\"", r->uri, reqs[x].requirement);
          }
      }
  
      if (!method_restricted) {
          return OK;
      }
  
      if (!conf->authoritative) {
          return DECLINED;
      }
  
      ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                    "access to %s failed, reason: user %s not allowed access",
                    r->uri, user);
          
      ap_note_basic_auth_failure(r);
      return HTTP_UNAUTHORIZED;
  }
  
  static void register_hooks(apr_pool_t *p)
  {
      ap_hook_check_user_id(authenticate_basic_user,NULL,NULL,APR_HOOK_MIDDLE);
      ap_hook_auth_checker(check_user_access,NULL,NULL,APR_HOOK_MIDDLE);
  }
  
  module AP_MODULE_DECLARE_DATA auth_basic_module =
  {
      STANDARD20_MODULE_STUFF,
      create_auth_dir_config,     /* dir config creater */
      NULL,                       /* dir merger --- default is to override */
      NULL,                       /* server config */
      NULL,                       /* merge server config */
      auth_basic_cmds,            /* command apr_table_t */
      register_hooks              /* register hooks */
  };
  
  
  
  1.1                  httpd-2.0/modules/aaa/mod_authn_anon.c
  
  Index: mod_authn_anon.c
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * Portions of this software are based upon public domain software
   * originally written at the National Center for Supercomputing Applications,
   * University of Illinois, Urbana-Champaign.
   */
  
  /*
   * http_auth: authentication
   * 
   * Rob McCool & Brian Behlendorf.
   * 
   * Adapted to Apache by rst.
   *
   * Version 0.5 May 1996
   *
   * Modified by Dirk.vanGulik@jrc.it to
   * 
   * Adapted to allow anonymous logins, just like with Anon-FTP, when
   * one gives the magic user name 'anonymous' and ones email address
   * as the password.
   *
   * Just add the following tokes to your <directory> setup:
   * 
   * Anonymous                    magic-userid [magic-userid]...
   *
   * Anonymous_MustGiveEmail      [ on | off ] default = on
   * Anonymous_LogEmail           [ on | off ] default = on
   * Anonymous_VerifyEmail        [ on | off ] default = off
   * Anonymous_NoUserId           [ on | off ] default = off
   * Anonymous_Authoritative      [ on | off ] default = off
   *
   * The magic user id is something like 'anonymous', it is NOT case sensitive. 
   * 
   * The MustGiveEmail flag can be used to force users to enter something
   * in the password field (like an email address). Default is on.
   *
   * Furthermore the 'NoUserID' flag can be set to allow completely empty
   * usernames in as well; this can be is convenient as a single return
   * in broken GUIs like W95 is often given by the user. The Default is off.
   *
   * Dirk.vanGulik@jrc.it; http://ewse.ceo.org; http://me-www.jrc.it/~dirkx
   * 
   */
  
  #include "apr_strings.h"
  
  #define APR_WANT_STRFUNC
  #include "apr_want.h"
  
  #include "httpd.h"
  #include "http_config.h"
  #include "http_core.h"
  #include "http_log.h"
  #include "http_request.h"
  #include "http_protocol.h"
  
  typedef struct anon_auth_pw {
      char *password;
      struct anon_auth_pw *next;
  } anon_auth_pw;
  
  typedef struct {
      anon_auth_pw *passwords;
      int nouserid;
      int logemail;
      int verifyemail;
      int mustemail;
      int authoritative;
  } authn_anon_config_rec;
  
  static void *create_authn_anon_dir_config(apr_pool_t *p, char *d)
  {
      authn_anon_config_rec *conf = apr_palloc(p, sizeof(*conf));
  
      /* just to illustrate the defaults really. */
      conf->passwords = NULL;
  
      conf->nouserid = 0;
      conf->logemail = 1;
      conf->verifyemail = 0;
      conf->mustemail = 1;
      conf->authoritative = 0;
      return conf;
  }
  
  static const char *anon_set_string_slots(cmd_parms *cmd,
                                           void *my_config, const char *arg)
  {
      authn_anon_config_rec *conf = my_config;
      anon_auth_pw *first;
  
      if (!(*arg)) {
          return "Anonymous string cannot be empty, use Anonymous_NoUserId";
      }
  
      /* squeeze in a record */
      first = conf->passwords;
  
      if (!(conf->passwords = apr_palloc(cmd->pool, sizeof(anon_auth_pw))) ||
          !(conf->passwords->password = apr_pstrdup(cmd->pool, arg))) {
          return "Failed to claim memory for an anonymous password...";
      }
  
      /* and repair the next */
      conf->passwords->next = first;
  
      return NULL;
  }
  
  static const command_rec authn_anon_cmds[] =
  {
      AP_INIT_ITERATE("Anonymous", anon_set_string_slots, NULL, OR_AUTHCFG, 
       "a space-separated list of user IDs"),
      AP_INIT_FLAG("Anonymous_MustGiveEmail", ap_set_flag_slot,
       (void *)APR_OFFSETOF(authn_anon_config_rec, mustemail),
       OR_AUTHCFG, "Limited to 'on' or 'off'"),
      AP_INIT_FLAG("Anonymous_NoUserId", ap_set_flag_slot,
       (void *)APR_OFFSETOF(authn_anon_config_rec, nouserid),
       OR_AUTHCFG, "Limited to 'on' or 'off'"),
      AP_INIT_FLAG("Anonymous_VerifyEmail", ap_set_flag_slot,
       (void *)APR_OFFSETOF(authn_anon_config_rec, verifyemail),
       OR_AUTHCFG, "Limited to 'on' or 'off'"),
      AP_INIT_FLAG("Anonymous_LogEmail", ap_set_flag_slot,
       (void *)APR_OFFSETOF(authn_anon_config_rec, logemail),
       OR_AUTHCFG, "Limited to 'on' or 'off'"),
      AP_INIT_FLAG("Anonymous_Authoritative", ap_set_flag_slot,
       (void *)APR_OFFSETOF(authn_anon_config_rec, authoritative),
       OR_AUTHCFG, "Limited to 'on' or 'off'"),
      {NULL}
  };
  
  module AP_MODULE_DECLARE_DATA authn_anon_module;
  
  static int anon_authenticate_basic_user(request_rec *r)
  {
      authn_anon_config_rec *conf = ap_get_module_config(r->per_dir_config,
                                                        &authn_anon_module);
      const char *sent_pw;
      int res = DECLINED;
  
      if ((res = ap_get_basic_auth_pw(r, &sent_pw))) {
          return res;
      }
  
      /* Ignore if we are not configured */
      if (!conf->passwords) {
          return DECLINED;
      }
  
      /* Do we allow an empty userID and/or is it the magic one
       */
  
      if ((!(r->user[0])) && (conf->nouserid)) {
          res = OK;
      }
      else {
          anon_auth_pw *p = conf->passwords;
          res = DECLINED;
          while ((res == DECLINED) && (p != NULL)) {
              if (!(strcasecmp(r->user, p->password))) {
                  res = OK;
              }
              p = p->next;
          }
      }
      /* Is username is OK and password been filled out (if required) */
      if ((res == OK) && ((!conf->mustemail) || strlen(sent_pw)) &&
          /* does the password look like an email address ? */
          ((!conf->verifyemail) ||
            ((strpbrk("@", sent_pw) != NULL) && 
             (strpbrk(".", sent_pw) != NULL)))) {
          if (conf->logemail && ap_is_initial_req(r)) {
              ap_log_rerror(APLOG_MARK, APLOG_INFO, APR_SUCCESS, r,
                          "Anonymous: Passwd <%s> Accepted",
                          sent_pw ? sent_pw : "\'none\'");
          }
          return OK;
      }
      else {
          if (conf->authoritative) {
              ap_log_rerror(APLOG_MARK, APLOG_ERR, APR_SUCCESS, r,
                          "Anonymous: Authoritative, Passwd <%s> not accepted",
                          sent_pw ? sent_pw : "\'none\'");
              return HTTP_UNAUTHORIZED;
          }
          /* Drop out the bottom to return DECLINED */
      }
  
      return DECLINED;
  }
  
  static void register_hooks(apr_pool_t *p)
  {
      ap_hook_check_user_id(anon_authenticate_basic_user,NULL,NULL,APR_HOOK_MIDDLE);
  }
  
  module AP_MODULE_DECLARE_DATA authn_anon_module =
  {
      STANDARD20_MODULE_STUFF,
      create_authn_anon_dir_config, /* dir config creater */
      NULL,                         /* dir merger ensure strictness */
      NULL,                         /* server config */
      NULL,                         /* merge server config */
      authn_anon_cmds,              /* command apr_table_t */
      register_hooks                /* register hooks */
  };
  
  
  
  1.1                  httpd-2.0/modules/aaa/mod_authn_dbm.c
  
  Index: mod_authn_dbm.c
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * Portions of this software are based upon public domain software
   * originally written at the National Center for Supercomputing Applications,
   * University of Illinois, Urbana-Champaign.
   */
  
  /*
   * http_auth: authentication
   * 
   * Rob McCool & Brian Behlendorf.
   * 
   * Adapted to Apache by rst.
   *
   * dirkx - Added Authoritative control to allow passing on to lower  
   *         modules if and only if the userid is not known to this
   *         module. A known user with a faulty or absent password still
   *         causes an AuthRequired. The default is 'Authoritative', i.e.
   *         no control is passed along.
   */
  
  #define APR_WANT_STRFUNC
  #include "apr_want.h"
  #include "apr_strings.h"
  #include "apr_dbm.h"
  #include "apr_md5.h"        /* for apr_password_validate */
  
  #include "httpd.h"
  #include "http_config.h"
  #include "http_core.h"
  #include "http_log.h"
  #include "http_protocol.h"
  #include "http_request.h"   /* for ap_hook_(check_user_id | auth_checker)*/
  
  
  typedef struct {
      char *pwfile;
      char *dbmtype;
      int authoritative;
  } authn_dbm_config_rec;
  
  static void *create_authn_dbm_dir_config(apr_pool_t *p, char *d)
  {
      authn_dbm_config_rec *conf = apr_palloc(p, sizeof(*conf));
  
      conf->pwfile = NULL;
      conf->dbmtype = "default";
      conf->authoritative = 1;  /* fortress is secure by default */
  
      return conf;
  }
  
  static const char *set_dbm_type(cmd_parms *cmd, 
                                  void *dir_config, 
                                  const char *arg)
  {
      authn_dbm_config_rec *conf = dir_config;
     
      conf->dbmtype = apr_pstrdup(cmd->pool, arg);
      return NULL;
  }
  
  static const command_rec authn_dbm_cmds[] =
  {
      AP_INIT_TAKE1("AuthDBMUserFile", ap_set_file_slot,
       (void *)APR_OFFSETOF(authn_dbm_config_rec, pwfile),
       OR_AUTHCFG, "dbm database file containing user IDs and passwords"),
      AP_INIT_TAKE1("AuthDBMType", set_dbm_type,
       NULL,
       OR_AUTHCFG, "what type of DBM file the user file is"),
      AP_INIT_FLAG("AuthDBMAuthoritative", ap_set_flag_slot,
       (void *)APR_OFFSETOF(authn_dbm_config_rec, authoritative),
       OR_AUTHCFG, "Set to 'no' to allow access control to be passed along to lower modules, if the UserID is not known in this module"),
      {NULL}
  };
  
  module AP_MODULE_DECLARE_DATA authn_dbm_module;
  
  /* This should go into APR; perhaps with some nice
   * caching/locking/flocking of the open dbm file.
   *
   * Duplicated in mod_auth_dbm.c
   */
  static apr_status_t
  get_dbm_entry_as_str(request_rec *r, 
                       char *user, 
                       char *auth_dbmfile, 
                       char *dbtype,
                       char **str)
  {
      apr_dbm_t *f;
      apr_datum_t d, q;
      char *pw = NULL;
      apr_status_t retval;
      q.dptr = user;
  
  #ifndef NETSCAPE_DBM_COMPAT
      q.dsize = strlen(q.dptr);
  #else
      q.dsize = strlen(q.dptr) + 1;
  #endif
  
      retval = apr_dbm_open_ex(&f, dbtype, auth_dbmfile, APR_DBM_READONLY, 
                               APR_OS_DEFAULT, r->pool);
  
      if (retval != APR_SUCCESS) {
          return retval;
      }
  
      *str = NULL;
  
      if (apr_dbm_fetch(f, q, &d) == APR_SUCCESS && d.dptr) {
          *str = apr_palloc(r->pool, d.dsize + 1);
          strncpy(pw, d.dptr, d.dsize);
          *str[d.dsize] = '\0'; /* Terminate the string */
      }
  
      apr_dbm_close(f);
  
      return retval;
  }
  
  static int dbm_authenticate_basic_user(request_rec *r)
  {
      authn_dbm_config_rec *conf = ap_get_module_config(r->per_dir_config,
                                                       &authn_dbm_module);
      const char *sent_pw;
      char *real_pw,*colon_pw;
      apr_status_t status;
      int res;
  
      if ((res = ap_get_basic_auth_pw(r, &sent_pw))) {
          return res;
      }
  
      if (!conf->pwfile) {
          return DECLINED;
      }
  
      status = get_dbm_entry_as_str(r, r->user, conf->pwfile,
                                    conf->dbmtype, &real_pw);
  
      if (status != APR_SUCCESS) {
          ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r,
                        "could not open dbm (type %s) user auth file: %s",
                        conf->dbmtype, 
                        conf->pwfile);
          return HTTP_INTERNAL_SERVER_ERROR;
      }
  
      if(real_pw == NULL) {
  
          if (!conf->authoritative) {
              return DECLINED;
          }
          ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                        "DBM user %s not found: %s", r->user, r->filename);
          ap_note_basic_auth_failure(r);
  
          return HTTP_UNAUTHORIZED;
      }
  
      /* Password is up to first : if exists */
      colon_pw = strchr(real_pw, ':');
      if (colon_pw) {
          *colon_pw = '\0';
      }
  
      status = apr_password_validate(sent_pw, real_pw);
  
      if (status != APR_SUCCESS) {
          ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                        "DBM user %s: authentication failure for \"%s\": "
                        "Password Mismatch",
                        r->user, r->uri);
          ap_note_basic_auth_failure(r);
          return HTTP_UNAUTHORIZED;
      }
      return OK;
  }
  
  static void register_hooks(apr_pool_t *p)
  {
      ap_hook_check_user_id(dbm_authenticate_basic_user, NULL, NULL,
                            APR_HOOK_MIDDLE);
  }
  
  module AP_MODULE_DECLARE_DATA authn_dbm_module =
  {
      STANDARD20_MODULE_STUFF,
      create_authn_dbm_dir_config, /* dir config creater */
      NULL,                        /* dir merger --- default is to override */
      NULL,                        /* server config */
      NULL,                        /* merge server config */
      authn_dbm_cmds,              /* command apr_table_t */
      register_hooks               /* register hooks */
  };
  
  
  
  1.1                  httpd-2.0/modules/aaa/mod_authn_default.c
  
  Index: mod_authn_default.c
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * Portions of this software are based upon public domain software
   * originally written at the National Center for Supercomputing Applications,
   * University of Illinois, Urbana-Champaign.
   */
  
  /*
   * http_auth: authentication
   * 
   * Rob McCool
   * 
   * Adapted to Apache by rst.
   *
   * dirkx - Added Authoritative control to allow passing on to lower
   *         modules if and only if the userid is not known to this
   *         module. A known user with a faulty or absent password still
   *         causes an AuthRequired. The default is 'Authoritative', i.e.
   *         no control is passed along.
   */
  
  #include "apr_strings.h"
  #include "apr_md5.h"            /* for apr_password_validate */
  
  #include "ap_config.h"
  #include "httpd.h"
  #include "http_config.h"
  #include "http_core.h"
  #include "http_log.h"
  #include "http_protocol.h"
  #include "http_request.h"
  
  typedef struct {
      int authoritative;
  } authn_default_config_rec;
  
  static void *create_authn_default_dir_config(apr_pool_t *p, char *d)
  {
      authn_default_config_rec *conf = apr_palloc(p, sizeof(*conf));
  
      conf->authoritative = 1; /* keep the fortress secure by default */
      return conf;
  }
  
  static const command_rec authn_default_cmds[] =
  {
      AP_INIT_FLAG("AuthDefaultAuthoritative", ap_set_flag_slot,
                   (void *)APR_OFFSETOF(authn_default_config_rec,
                                        authoritative),
                   OR_AUTHCFG,
                   "Set to 'no' to allow access control to be passed along to "
                   "lower modules if the UserID is not known to this module. "
  		         "(default is yes)."),
      {NULL}
  };
  
  module AP_MODULE_DECLARE_DATA authn_default_module;
  
  static int authenticate_basic_user(request_rec *r)
  {
      authn_default_config_rec *conf = ap_get_module_config(r->per_dir_config,
                                                        &authn_default_module);
      const char *sent_pw;
      int res;
  
      if ((res = ap_get_basic_auth_pw(r, &sent_pw))) {
         	return res;
      }
  
      if (conf->authoritative == 0) {
  	    return DECLINED;
      }
  
      ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                    "access to %s failed, reason: verification of user id '%s' "
                    "not configured",
                    r->uri, r->user ? r->user : "<null>");
  
      ap_note_basic_auth_failure(r);
      return HTTP_UNAUTHORIZED;
  }
  
  static void register_hooks(apr_pool_t *p)
  {
      ap_hook_check_user_id(authenticate_basic_user,NULL,NULL,APR_HOOK_LAST);
  }
  
  module AP_MODULE_DECLARE_DATA authn_default_module =
  {
      STANDARD20_MODULE_STUFF,
      create_authn_default_dir_config,/* dir config creater */
      NULL,                           /* dir merger --- default is to override */
      NULL,                           /* server config */
      NULL,                           /* merge server config */
      authn_default_cmds,             /* command apr_table_t */
      register_hooks                  /* register hooks */
  };
  
  
  
  1.1                  httpd-2.0/modules/aaa/mod_authn_file.c
  
  Index: mod_authn_file.c
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * Portions of this software are based upon public domain software
   * originally written at the National Center for Supercomputing Applications,
   * University of Illinois, Urbana-Champaign.
   */
  
  /*
   * http_auth: authentication
   * 
   * Rob McCool
   * 
   * Adapted to Apache by rst.
   *
   * dirkx - Added Authoritative control to allow passing on to lower
   *         modules if and only if the userid is not known to this
   *         module. A known user with a faulty or absent password still
   *         causes an AuthRequired. The default is 'Authoritative', i.e.
   *         no control is passed along.
   */
  
  #include "apr_strings.h"
  #include "apr_md5.h"            /* for apr_password_validate */
  
  #include "ap_config.h"
  #include "httpd.h"
  #include "http_config.h"
  #include "http_core.h"
  #include "http_log.h"
  #include "http_protocol.h"
  #include "http_request.h"
  
  typedef struct {
      char *pwfile;
      int authoritative;
  } authn_file_config_rec;
  
  static void *create_authn_file_dir_config(apr_pool_t *p, char *d)
  {
      authn_file_config_rec *conf = apr_palloc(p, sizeof(*conf));
  
      conf->pwfile = NULL;     /* just to illustrate the default really */
      conf->authoritative = 1; /* keep the fortress secure by default */
      return conf;
  }
  
  static const char *set_authn_file_slot(cmd_parms *cmd, void *offset,
                                         const char *f, const char *t)
  {
      if (t && strcmp(t, "standard")) {
          return apr_pstrcat(cmd->pool, "Invalid auth file type: ", t, NULL);
      }
  
      return ap_set_file_slot(cmd, offset, f);
  }
  
  static const command_rec authn_file_cmds[] =
  {
      AP_INIT_TAKE12("AuthUserFile", set_authn_file_slot,
                     (void *)APR_OFFSETOF(authn_file_config_rec, pwfile),
                     OR_AUTHCFG, "text file containing user IDs and passwords"),
      AP_INIT_FLAG("AuthUserFileAuthoritative", ap_set_flag_slot,
                   (void *)APR_OFFSETOF(authn_file_config_rec, authoritative),
                   OR_AUTHCFG,
                   "Set to 'no' to allow access control to be passed along to "
                   "other modules if the BasicAuth username is not in "
                   "AuthUserFile. (default is yes)." ),
      {NULL}
  };
  
  module AP_MODULE_DECLARE_DATA authn_file_module;
  
  static apr_status_t get_pw(request_rec *r, char *user, char *pwfile, 
                             char ** out)
  {
      ap_configfile_t *f;
      char l[MAX_STRING_LEN];
      const char *rpw, *w;
      apr_status_t status;
  
      *out = NULL;
  
      if ((status = ap_pcfg_openfile(&f, r->pool, pwfile)) != APR_SUCCESS) {
          return status;
      }
  
      while (!(ap_cfg_getline(l, MAX_STRING_LEN, f))) {
          if ((l[0] == '#') || (!l[0])) {
              continue;
          }
          rpw = l;
          w = ap_getword(r->pool, &rpw, ':');
  
          if (!strcmp(user, w)) {
              ap_cfg_closefile(f);
              *out = ap_getword(r->pool, &rpw, ':');
              return APR_SUCCESS;
          }
      }
      ap_cfg_closefile(f);
  
      return APR_SUCCESS;
  }
  
  /* These functions return 0 if client is OK, and proper error status
   * if not... either HTTP_UNAUTHORIZED, if we made a check, and it failed, or
   * HTTP_INTERNAL_SERVER_ERROR, if things are so totally confused that we
   * couldn't figure out how to tell if the client is authorized or not.
   *
   * If they return DECLINED, and all other modules also decline, that's
   * treated by the server core as a configuration error, logged and
   * reported as such.
   */
  
  /* Determine user ID, and check if it really is that user, for HTTP
   * basic authentication...
   */
  
  static int authenticate_basic_user(request_rec *r)
  {
      authn_file_config_rec *conf = ap_get_module_config(r->per_dir_config,
                                                         &authn_file_module);
      const char *sent_pw;
      char *real_pw = NULL;
      apr_status_t status;
      int res;
  
      if ((res = ap_get_basic_auth_pw(r, &sent_pw))) {
          return res;
      }
  
      if (!conf->pwfile) {
          return DECLINED;
      }
  
      if ((status = get_pw(r, r->user, conf->pwfile, &real_pw)) != APR_SUCCESS) 
      {
          ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r,
                        "Could not open password file: %s", conf->pwfile);
          return HTTP_INTERNAL_SERVER_ERROR;
      }
  
      if (real_pw == NULL) {
          if (!conf->authoritative) {
             return DECLINED;
          } 
          ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                        "user %s not found: %s", r->user, r->uri);
          ap_note_basic_auth_failure(r);
          return HTTP_UNAUTHORIZED;
      }
  
      status = apr_password_validate(sent_pw, real_pw);
  
      if (status != APR_SUCCESS) {
          ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                        "user %s: authentication failure for \"%s\": "
                        "Password Mismatch",
                        r->user, r->uri);
          ap_note_basic_auth_failure(r);
          return HTTP_UNAUTHORIZED;
      }
  
      return OK;
  }
  
  static void register_hooks(apr_pool_t *p)
  {
      ap_hook_check_user_id(authenticate_basic_user,NULL,NULL,APR_HOOK_MIDDLE);
  }
  
  module AP_MODULE_DECLARE_DATA authn_file_module =
  {
      STANDARD20_MODULE_STUFF,
      create_authn_file_dir_config,    /* dir config creater */
      NULL,                            /* dir merger --- default is to override */
      NULL,                            /* server config */
      NULL,                            /* merge server config */
      authn_file_cmds,                 /* command apr_table_t */
      register_hooks                   /* register hooks */
  };
  
  
  
  1.1                  httpd-2.0/modules/aaa/mod_authz_dbm.c
  
  Index: mod_authz_dbm.c
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * Portions of this software are based upon public domain software
   * originally written at the National Center for Supercomputing Applications,
   * University of Illinois, Urbana-Champaign.
   */
  
  /*
   * http_auth: authentication
   * 
   * Rob McCool & Brian Behlendorf.
   * 
   * Adapted to Apache by rst.
   *
   * dirkx - Added Authoritative control to allow passing on to lower  
   *         modules if and only if the userid is not known to this
   *         module. A known user with a faulty or absent password still
   *         causes an AuthRequired. The default is 'Authoritative', i.e.
   *         no control is passed along.
   */
  
  #define APR_WANT_STRFUNC
  #include "apr_want.h"
  #include "apr_strings.h"
  #include "apr_dbm.h"
  #include "apr_md5.h"
  
  #include "httpd.h"
  #include "http_config.h"
  #include "http_core.h"
  #include "http_log.h"
  #include "http_protocol.h"
  #include "http_request.h"   /* for ap_hook_(check_user_id | auth_checker)*/
  
  typedef struct {
      char *grpfile;
      char *dbmtype;
      int authoritative;
  } authz_dbm_config_rec;
  
  /* This should go into APR; perhaps with some nice
   * caching/locking/flocking of the open dbm file.
   *
   * Duplicated in mod_auth_dbm.c
   */
  static apr_status_t get_dbm_entry_as_str(request_rec *r, char *user,
                                           char *auth_dbmfile, char *dbtype,
                                           char ** str)
  {
      apr_dbm_t *f;
      apr_datum_t d, q;
      char *pw = NULL;
      apr_status_t retval;
      q.dptr = user;
  
  #ifndef NETSCAPE_DBM_COMPAT
      q.dsize = strlen(q.dptr);
  #else
      q.dsize = strlen(q.dptr) + 1;
  #endif
  
      retval = apr_dbm_open_ex(&f, dbtype, auth_dbmfile, APR_DBM_READONLY, 
                               APR_OS_DEFAULT, r->pool);
  
      if (retval != APR_SUCCESS) {
          return retval;
      }
  
      *str = NULL;
  
      if (apr_dbm_fetch(f, q, &d) == APR_SUCCESS && d.dptr) {
          *str = apr_palloc(r->pool, d.dsize + 1);
          strncpy(pw, d.dptr, d.dsize);
          *str[d.dsize] = '\0'; /* Terminate the string */
      }
  
      apr_dbm_close(f);
  
      return retval;
  }
  
  static void *create_authz_dbm_dir_config(apr_pool_t *p, char *d)
  {
      authz_dbm_config_rec *conf = apr_palloc(p, sizeof(*conf));
  
      conf->grpfile = NULL;
      conf->dbmtype = "default";
      conf->authoritative = 1;  /* fortress is secure by default */
  
      return conf;
  }
  
  static const command_rec authz_dbm_cmds[] =
  {
      AP_INIT_TAKE1("AuthzDBMGroupFile", ap_set_file_slot,
       (void *)APR_OFFSETOF(authz_dbm_config_rec, grpfile),
       OR_AUTHCFG, "database file containing group names and member user IDs"),
      AP_INIT_TAKE1("AuthzDBMType", ap_set_string_slot,
       (void *)APR_OFFSETOF(authz_dbm_config_rec, dbmtype),
       OR_AUTHCFG, "what type of DBM file the group file is"),
      AP_INIT_FLAG("AuthzDBMAuthoritative", ap_set_flag_slot,
       (void *)APR_OFFSETOF(authz_dbm_config_rec, authoritative),
       OR_AUTHCFG, "Set to 'no' to allow access control to be passed along to "
       "lower modules, if the group required is not found or empty, or the user "
       " is not in the required groups. (default is yes.)"),
      {NULL}
  };
  
  module AP_MODULE_DECLARE_DATA authz_dbm_module;
  
  /* We do something strange with the group file.  If the group file
   * contains any : we assume the format is
   *      key=username value=":"groupname [":"anything here is ignored]
   * otherwise we now (0.8.14+) assume that the format is
   *      key=username value=groupname
   * The first allows the password and group files to be the same 
   * physical DBM file;   key=username value=password":"groupname[":"anything]
   *
   * mark@telescope.org, 22Sep95
   */
  
  static apr_status_t get_dbm_grp(request_rec *r, char *user, char *dbmgrpfile, 
                                  char *dbtype, const char ** out)
  {
      char *grp_data;
      char *grp_colon;
      char *grp_colon2;
  
      apr_status_t status = get_dbm_entry_as_str(r, user, dbmgrpfile,
                                                 dbtype, &grp_data);
  
      if (status != APR_SUCCESS) {
          return status;
      }
  
      *out = NULL;
  
      if (grp_data == NULL) {
          return APR_SUCCESS;
      }
  
      if ((grp_colon = strchr(grp_data, ':')) != NULL) {
          grp_colon2 = strchr(++grp_colon, ':');
          if (grp_colon2) {
              *grp_colon2 = '\0';
          }
          *out = grp_colon;
          return APR_SUCCESS;
      }
  
      return APR_SUCCESS;
  }
  
  /* Checking ID */
  static int dbm_check_auth(request_rec *r)
  {
      authz_dbm_config_rec *conf = ap_get_module_config(r->per_dir_config,
                                                        &authz_dbm_module);
      char *user = r->user;
      int m = r->method_number;
      int required = 0;
      const apr_array_header_t *reqs_arr = ap_requires(r);
      require_line *reqs = reqs_arr ? (require_line *) reqs_arr->elts : NULL;
      register int x;
      const char *t;
      char *w;
      apr_status_t status;
  
      if (!conf->grpfile) {
          return DECLINED;
      }
  
      if (!reqs_arr) {
          return DECLINED;
      }
  
      for (x = 0; x < reqs_arr->nelts; x++) {
  
          required |= 1;
  
          if (!(reqs[x].method_mask & (AP_METHOD_BIT << m))) {
              continue;
          }
  
          t = reqs[x].requirement;
          w = ap_getword_white(r->pool, &t);
   
          if (!strcmp(w, "group")) {
              const char *orig_groups, *groups;
              char *v;
  
              required |= 2;
  
              status = get_dbm_grp(r, user, conf->grpfile, conf->dbmtype,
                                   &groups);
  
              if (status != APR_SUCCESS) {
                  ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r,
                        "could not open dbm (type %s) group access file: %s", 
                          conf->dbmtype, conf->grpfile);
                  return HTTP_INTERNAL_SERVER_ERROR;
             }
  
             if (groups == NULL) {
                  if (!conf->authoritative) {
                      return DECLINED;
                  }
  
                  ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                              "user %s not in DBM group file %s: %s",
                              user, conf->grpfile, r->filename);
  
                  ap_note_basic_auth_failure(r);
                  return HTTP_UNAUTHORIZED;
              }
  
              orig_groups = groups;
              while (t[0]) {
                  w = ap_getword_white(r->pool, &t);
                  groups = orig_groups;
                  while (groups[0]) {
                      v = ap_getword(r->pool, &groups, ',');
                      if (!strcmp(v, w)) {
                          return OK;
                      }
                  }
              }
              ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                            "user %s not in right group: %s",
                            user, r->filename);
              ap_note_basic_auth_failure(r);
              return HTTP_UNAUTHORIZED;
          }
      }
  
      return DECLINED;
  }
  
  static void register_hooks(apr_pool_t *p)
  {
      ap_hook_auth_checker(dbm_check_auth, NULL, NULL, APR_HOOK_MIDDLE);
  }
  
  module AP_MODULE_DECLARE_DATA authz_dbm_module =
  {
      STANDARD20_MODULE_STUFF,
      create_authz_dbm_dir_config, /* dir config creater */
      NULL,                        /* dir merger --- default is to override */
      NULL,                        /* server config */
      NULL,                        /* merge server config */
      authz_dbm_cmds,              /* command apr_table_t */
      register_hooks               /* register hooks */
  };
  
  
  
  1.1                  httpd-2.0/modules/aaa/mod_authz_default.c
  
  Index: mod_authz_default.c
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * Portions of this software are based upon public domain software
   * originally written at the National Center for Supercomputing Applications,
   * University of Illinois, Urbana-Champaign.
   */
  
  /*
   * http_auth: authentication
   * 
   * Rob McCool
   * 
   * Adapted to Apache by rst.
   *
   * dirkx - Added Authoritative control to allow passing on to lower
   *         modules if and only if the userid is not known to this
   *         module. A known user with a faulty or absent password still
   *         causes an AuthRequired. The default is 'Authoritative', i.e.
   *         no control is passed along.
   */
  
  #include "apr_strings.h"
  #include "apr_md5.h"            /* for apr_password_validate */
  
  #include "ap_config.h"
  #include "httpd.h"
  #include "http_config.h"
  #include "http_core.h"
  #include "http_log.h"
  #include "http_protocol.h"
  #include "http_request.h"
  
  typedef struct {
      int authoritative;
  } authz_default_config_rec;
  
  static void *create_authz_default_dir_config(apr_pool_t *p, char *d)
  {
      authz_default_config_rec *conf = apr_palloc(p, sizeof(*conf));
  
      conf->authoritative = 1; /* keep the fortress secure by default */
      return conf;
  }
  
  static const command_rec authz_default_cmds[] =
  {
      AP_INIT_FLAG("AccessAuthoritative", ap_set_flag_slot,
                   (void *)APR_OFFSETOF(authz_default_config_rec, authoritative),
                   OR_AUTHCFG,
                   "Set to 'no' to allow access control to be passed along to "
                   "lower modules. (default is yes.)"),
      {NULL}
  };
  
  module AP_MODULE_DECLARE_DATA authz_default_module;
  
  static int check_user_access(request_rec *r)
  {
      authz_default_config_rec *conf = ap_get_module_config(r->per_dir_config,
                                                   &authz_default_module);
      int m = r->method_number;
      int method_restricted = 0;
      register int x;
      const apr_array_header_t *reqs_arr = ap_requires(r);
      require_line *reqs;
  
      /* BUG FIX: tadc, 11-Nov-1995.  If there is no "requires" directive, 
       * then any user will do.
       */
      if (!reqs_arr) {
          return OK;
      }
      reqs = (require_line *)reqs_arr->elts;
  
      for (x = 0; x < reqs_arr->nelts; x++) {
          if (!(reqs[x].method_mask & (AP_METHOD_BIT << m))) {
              continue;
          }
          method_restricted = 1;
          break;
      }
  
      if (method_restricted == 0) {
          return OK;
      }
  
      if (!(conf->authoritative)) {
          return DECLINED;
      }
  
      /* if we aren't authoritative, any require directive could be
       * considered valid even if noone groked it.  However, if we are 
       * authoritative, we can warn the user they did something wrong.
       *
       * That something could be a missing "AuthAuthoritative off", but
       * more likely is a typo in the require directive.
       */
      ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                            "access to %s failed, reason: require directives "
                            "present and no Authoritative handler.", r->uri);
  
      ap_note_basic_auth_failure(r);
      return HTTP_UNAUTHORIZED;
  }
  
  static void register_hooks(apr_pool_t *p)
  {
      ap_hook_auth_checker(check_user_access,NULL,NULL,APR_HOOK_LAST);
  }
  
  module AP_MODULE_DECLARE_DATA authz_default_module =
  {
      STANDARD20_MODULE_STUFF,
      create_authz_default_dir_config, /* dir config creater */
      NULL,                            /* dir merger --- default is to override */
      NULL,                            /* server config */
      NULL,                            /* merge server config */
      authz_default_cmds,              /* command apr_table_t */
      register_hooks                   /* register hooks */
  };
  
  
  
  1.1                  httpd-2.0/modules/aaa/mod_authz_groupfile.c
  
  Index: mod_authz_groupfile.c
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * Portions of this software are based upon public domain software
   * originally written at the National Center for Supercomputing Applications,
   * University of Illinois, Urbana-Champaign.
   */
  
  /* This module is triggered by an
   *
   *          AuthzGroupFile standard /path/to/file
   *
   * and the presense of a
   *
   *         require group <list-of-groups>
   * 
   * In an applicable limit/directory block for that method.
   *
   * If there are no AuthzGroupFile directives valid for 
   * the request; we DECLINED.
   * 
   * If the AuthzGroupFile is defined; but somehow not
   * accessible: we SERVER_ERROR (was DECLINED).
   *
   * If there are no 'require ' directives defined for
   * this request then we DECLINED (was OK).
   * 
   * If there are no 'require ' directives valid for
   * this request method then we DECLINED. (was OK)
   *
   * If there are any 'require group' blocks and we
   * are not in any group - we HTTP_UNAUTHORIZE
   * unless we are non-authoritative; in which  
   * case we DECLINED.
   *
   */
  
  #include "apr_strings.h"
  #include "apr_md5.h"            /* for apr_password_validate */
  
  #include "ap_config.h"
  #include "httpd.h"
  #include "http_config.h"
  #include "http_core.h"
  #include "http_log.h"
  #include "http_protocol.h"
  #include "http_request.h"
  
  typedef struct {
      char *groupfile;
      int authoritative;
  } authz_groupfile_config_rec;
  
  static void *create_authz_groupfile_dir_config(apr_pool_t *p, char *d)
  {
      authz_groupfile_config_rec *conf = apr_palloc(p, sizeof(*conf));
  
      conf->groupfile = NULL;    
      conf->authoritative = 1; /* keep the fortress secure by default */
      return conf;
  }
  
  static const char *set_authz_groupfile_slot(cmd_parms *cmd, void *offset, const char *f, 
                                   const char *t)
  {
      if (t && strcmp(t, "standard")) {
          return apr_pstrcat(cmd->pool, "Invalid auth file type: ", t, NULL);
      }
  
      return ap_set_file_slot(cmd, offset, f);
  }
  
  static const command_rec authz_groupfile_cmds[] =
  {
      AP_INIT_TAKE12("AuthzGroupFile", set_authz_groupfile_slot,
                     (void *)APR_OFFSETOF(authz_groupfile_config_rec, groupfile),
                     OR_AUTHCFG,
                     "text file containing group names and member user IDs"),
      AP_INIT_FLAG("AuthzGroupFileAuthoritative", ap_set_flag_slot,
                   (void *)APR_OFFSETOF(authz_groupfile_config_rec,
                                        authoritative),
                   OR_AUTHCFG,
                   "Set to 'no' to allow access control to be passed along to "
                   "lower modules if the 'require group' fails. (default is "
                   "no)."),
      {NULL}
  };
  
  module AP_MODULE_DECLARE_DATA authz_groupfile_module;
  
  static apr_status_t groups_for_user(apr_pool_t *p, char *user, char *grpfile,
                                      apr_table_t ** out)
  {
      ap_configfile_t *f;
      apr_table_t *grps = apr_table_make(p, 15);
      apr_pool_t *sp;
      char l[MAX_STRING_LEN];
      const char *group_name, *ll, *w;
      apr_status_t status;
  
      if ((status = ap_pcfg_openfile(&f, p, grpfile)) != APR_SUCCESS) {
          return status ;
      }
  
      apr_pool_create(&sp, p);
  
      while (!(ap_cfg_getline(l, MAX_STRING_LEN, f))) {
          if ((l[0] == '#') || (!l[0])) {
              continue;
          }
          ll = l;
          apr_pool_clear(sp);
  
          group_name = ap_getword(sp, &ll, ':');
  
          while (ll[0]) {
              w = ap_getword_conf(sp, &ll);
              if (!strcmp(w, user)) {
                  apr_table_setn(grps, apr_pstrdup(p, group_name), "in");
                  break;
              }
          }
      }
      ap_cfg_closefile(f);
      apr_pool_destroy(sp);
  
      *out = grps;
      return APR_SUCCESS;
  }
  
  /* Checking ID */
  
  static int check_user_access(request_rec *r)
  {
      authz_groupfile_config_rec *conf = ap_get_module_config(r->per_dir_config,
                                                        &authz_groupfile_module);
      char *user = r->user;
      int m = r->method_number;
      int method_restricted = 0;
      register int x,has_entries;
      const char *t, *w;
      apr_table_t *grpstatus;
      const apr_array_header_t *reqs_arr = ap_requires(r);
      require_line *reqs;
      apr_status_t status;
  
      if (!reqs_arr) {
          return DECLINED; /* XXX change from legacy */
      } 
      
      reqs = (require_line *)reqs_arr->elts;
  
      /* If there is no group file - then we are not
       * configured. So decline. 
       */
      if (!(conf->groupfile))
           return DECLINED; 
  
      if ((status = groups_for_user(r->pool, user, conf->groupfile,
                                    &grpstatus)) != APR_SUCCESS) {
           ap_log_rerror(APLOG_MARK, APLOG_ERR, NULL, r,
                         "Could not open group file: %s", conf->groupfile);
           return HTTP_INTERNAL_SERVER_ERROR;
      };
  
      has_entries = apr_table_elts(grpstatus)->nelts;
  
      for (x = 0; x < reqs_arr->nelts; x++) {
  
          if (!(reqs[x].method_mask & (AP_METHOD_BIT << m))) {
              continue;
          }
          method_restricted |= 1;
  
          t = reqs[x].requirement;
          w = ap_getword_white(r->pool, &t);
  
          if (!strcmp(w, "group")) {
              method_restricted |= 2;
               if (has_entries) {
              while (t[0]) {
                  w = ap_getword_conf(r->pool, &t);
                  if (apr_table_get(grpstatus, w)) {
                      return OK;
                  }
              }
           }
          }
      }
  
      /* No applicable requires for this method seen at all */
      if (method_restricted == 0) {
          return DECLINED; /* XXX change from legacy */
      }
  
      /* No applicable "requires group" for this method seen */
      if ((method_restricted & 2) == 0) {
          return DECLINED;
      }
  
      if (!(conf->authoritative)) {
          return DECLINED;
      }
  
      ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                    "access to %s failed, reason: user %s not part of the "
                    "'require'ed group(s).", r->uri, user);
          
      ap_note_basic_auth_failure(r);
      return HTTP_UNAUTHORIZED;
  }
  
  static void register_hooks(apr_pool_t *p)
  {
      ap_hook_auth_checker(check_user_access,NULL,NULL,APR_HOOK_MIDDLE);
  }
  
  module AP_MODULE_DECLARE_DATA authz_groupfile_module =
  {
      STANDARD20_MODULE_STUFF,
      create_authz_groupfile_dir_config,/* dir config creater */
      NULL,                             /* dir merger -- default is to override */
      NULL,                             /* server config */
      NULL,                             /* merge server config */
      authz_groupfile_cmds,             /* command apr_table_t */
      register_hooks                    /* register hooks */
  };
  
  
  
  1.1                  httpd-2.0/modules/aaa/mod_authz_host.c
  
  Index: mod_authz_host.c
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * Portions of this software are based upon public domain software
   * originally written at the National Center for Supercomputing Applications,
   * University of Illinois, Urbana-Champaign.
   */
  
  /*
   * Security options etc.
   * 
   * Module derived from code originally written by Rob McCool
   * 
   */
  
  #include "apr_strings.h"
  #include "apr_network_io.h"
  #include "apr_md5.h"
  
  #define APR_WANT_STRFUNC
  #define APR_WANT_BYTEFUNC
  #include "apr_want.h"
  
  #include "ap_config.h"
  #include "httpd.h"
  #include "http_core.h"
  #include "http_config.h"
  #include "http_log.h"
  #include "http_request.h"
  
  #if APR_HAVE_NETINET_IN_H
  #include <netinet/in.h>
  #endif
  
  enum allowdeny_type {
      T_ENV,
      T_ALL,
      T_IP,
      T_HOST,
      T_FAIL
  };
  
  typedef struct {
      apr_int64_t limited;
      union {
          char *from;
          apr_ipsubnet_t *ip;
      } x;
      enum allowdeny_type type;
  } allowdeny;
  
  /* things in the 'order' array */
  #define DENY_THEN_ALLOW 0
  #define ALLOW_THEN_DENY 1
  #define MUTUAL_FAILURE 2
  
  typedef struct {
      int order[METHODS];
      apr_array_header_t *allows;
      apr_array_header_t *denys;
  } authz_host_dir_conf;
  
  module AP_MODULE_DECLARE_DATA authz_host_module;
  
  static void *create_authz_host_dir_config(apr_pool_t *p, char *dummy)
  {
      int i;
      authz_host_dir_conf *conf =
          (authz_host_dir_conf *)apr_pcalloc(p, sizeof(authz_host_dir_conf));
  
      for (i = 0; i < METHODS; ++i) {
          conf->order[i] = DENY_THEN_ALLOW;
      }
      conf->allows = apr_array_make(p, 1, sizeof(allowdeny));
      conf->denys = apr_array_make(p, 1, sizeof(allowdeny));
  
      return (void *)conf;
  }
  
  static const char *order(cmd_parms *cmd, void *dv, const char *arg)
  {
      authz_host_dir_conf *d = (authz_host_dir_conf *) dv;
      int i, o;
  
      if (!strcasecmp(arg, "allow,deny"))
          o = ALLOW_THEN_DENY;
      else if (!strcasecmp(arg, "deny,allow"))
          o = DENY_THEN_ALLOW;
      else if (!strcasecmp(arg, "mutual-failure"))
          o = MUTUAL_FAILURE;
      else
          return "unknown order";
  
      for (i = 0; i < METHODS; ++i)
          if (cmd->limited & (AP_METHOD_BIT << i))
              d->order[i] = o;
  
      return NULL;
  }
  
  static const char *allow_cmd(cmd_parms *cmd, void *dv, const char *from, 
                               const char *where_c)
  {
      authz_host_dir_conf *d = (authz_host_dir_conf *) dv;
      allowdeny *a;
      char *where = apr_pstrdup(cmd->pool, where_c);
      char *s;
      char msgbuf[120];
      apr_status_t rv;
  
      if (strcasecmp(from, "from"))
          return "allow and deny must be followed by 'from'";
  
      a = (allowdeny *) apr_array_push(cmd->info ? d->allows : d->denys);
      a->x.from = where;
      a->limited = cmd->limited;
  
      if (!strncasecmp(where, "env=", 4)) {
          a->type = T_ENV;
          a->x.from += 4;
  
      }
      else if (!strcasecmp(where, "all")) {
          a->type = T_ALL;
      }
      else if ((s = strchr(where, '/'))) {
          *s++ = '\0';
          rv = apr_ipsubnet_create(&a->x.ip, where, s, cmd->pool);
          if(APR_STATUS_IS_EINVAL(rv)) {
              /* looked nothing like an IP address */
              return "An IP address was expected";
          }
          else if (rv != APR_SUCCESS) {
              apr_strerror(rv, msgbuf, sizeof msgbuf);
              return apr_pstrdup(cmd->pool, msgbuf);
          }
          a->type = T_IP;
      }
      else if (!APR_STATUS_IS_EINVAL(rv = apr_ipsubnet_create(&a->x.ip, where, NULL, cmd->pool))) {
          if (rv != APR_SUCCESS) {
              apr_strerror(rv, msgbuf, sizeof msgbuf);
              return apr_pstrdup(cmd->pool, msgbuf);
          }
          a->type = T_IP;
      }
      else { /* no slash, didn't look like an IP address => must be a host */
          a->type = T_HOST;
      }
  
      return NULL;
  }
  
  static char its_an_allow;
  
  static const command_rec authz_host_cmds[] =
  {
      AP_INIT_TAKE1("order", order, NULL, OR_LIMIT,
                    "'allow,deny', 'deny,allow', or 'mutual-failure'"),
      AP_INIT_ITERATE2("allow", allow_cmd, &its_an_allow, OR_LIMIT,
                       "'from' followed by hostnames or IP-address wildcards"),
      AP_INIT_ITERATE2("deny", allow_cmd, NULL, OR_LIMIT,
                       "'from' followed by hostnames or IP-address wildcards"),
      {NULL}
  };
  
  static int in_domain(const char *domain, const char *what)
  {
      int dl = strlen(domain);
      int wl = strlen(what);
  
      if ((wl - dl) >= 0) {
          if (strcasecmp(domain, &what[wl - dl]) != 0) {
              return 0;
          }
  
          /* Make sure we matched an *entire* subdomain --- if the user
           * said 'allow from good.com', we don't want people from nogood.com
           * to be able to get in.
           */
  
          if (wl == dl) {
              return 1;                /* matched whole thing */
          }
          else {
              return (domain[0] == '.' || what[wl - dl - 1] == '.');
          }
      }
      else {
          return 0;
      }
  }
  
  static int find_allowdeny(request_rec *r, apr_array_header_t *a, int method)
  {
  
      allowdeny *ap = (allowdeny *) a->elts;
      apr_int64_t mmask = (AP_METHOD_BIT << method);
      int i;
      int gothost = 0;
      const char *remotehost = NULL;
  
      for (i = 0; i < a->nelts; ++i) {
          if (!(mmask & ap[i].limited)) {
              continue;
          }
  
          switch (ap[i].type) {
          case T_ENV:
              if (apr_table_get(r->subprocess_env, ap[i].x.from)) {
                  return 1;
              }
              break;
  
          case T_ALL:
              return 1;
  
          case T_IP:
              if (apr_ipsubnet_test(ap[i].x.ip, r->connection->remote_addr)) {
                  return 1;
              }
              break;
  
          case T_HOST:
              if (!gothost) {
                  int remotehost_is_ip;
  
                  remotehost = ap_get_remote_host(r->connection,
                                                  r->per_dir_config,
                                                  REMOTE_DOUBLE_REV,
                                                  &remotehost_is_ip);
  
                  if ((remotehost == NULL) || remotehost_is_ip) {
                      gothost = 1;
                  }
                  else {
                      gothost = 2;
                  }
              }
  
              if ((gothost == 2) && in_domain(ap[i].x.from, remotehost)) {
                  return 1;
              }
              break;
  
          case T_FAIL:
              /* do nothing? */
              break;
          }
      }
  
      return 0;
  }
  
  static int check_dir_access(request_rec *r)
  {
      int method = r->method_number;
      int ret = OK;
      authz_host_dir_conf *a = (authz_host_dir_conf *)
          ap_get_module_config(r->per_dir_config, &authz_host_module);
  
      if (a->order[method] == ALLOW_THEN_DENY) {
          ret = HTTP_FORBIDDEN;
          if (find_allowdeny(r, a->allows, method)) {
              ret = OK;
          }
          if (find_allowdeny(r, a->denys, method)) {
              ret = HTTP_FORBIDDEN;
          }
      }
      else if (a->order[method] == DENY_THEN_ALLOW) {
          if (find_allowdeny(r, a->denys, method)) {
              ret = HTTP_FORBIDDEN;
          }
          if (find_allowdeny(r, a->allows, method)) {
              ret = OK;
          }
      }
      else {
          if (find_allowdeny(r, a->allows, method)
              && !find_allowdeny(r, a->denys, method)) {
              ret = OK;
          }
          else {
              ret = HTTP_FORBIDDEN;
          }
      }
  
      if (ret == HTTP_FORBIDDEN
          && (ap_satisfies(r) != SATISFY_ANY || !ap_some_auth_required(r))) {
          ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
              "client denied by server configuration: %s",
              r->filename);
      }
  
      return ret;
  }
  
  static void register_hooks(apr_pool_t *p)
  {
      /* This can be access checker since we don't require r->user to be set. */
      ap_hook_access_checker(check_dir_access,NULL,NULL,APR_HOOK_MIDDLE);
  }
  
  module AP_MODULE_DECLARE_DATA authz_host_module =
  {
      STANDARD20_MODULE_STUFF,
      create_authz_host_dir_config,   /* dir config creater */
      NULL,                           /* dir merger --- default is to override */
      NULL,                           /* server config */
      NULL,                           /* merge server config */
      authz_host_cmds,
      register_hooks                  /* register hooks */
  };
  
  
  
  1.1                  httpd-2.0/modules/aaa/mod_authz_user.c
  
  Index: mod_authz_user.c
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000-2002 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * Portions of this software are based upon public domain software
   * originally written at the National Center for Supercomputing Applications,
   * University of Illinois, Urbana-Champaign.
   */
  
  /* http_auth: 
   * authentication
   * 
   * Rob McCool
   * 
   * Adapted to Apache by rst.
   *
   * dirkx - Added Authoritative control to allow passing on to lower
   *         modules if and only if the userid is not known to this
   *         module. A known user with a faulty or absent password still
   *         causes an AuthRequired. The default is 'Authoritative', i.e.
   *         no control is passed along.
   */
  
  #include "apr_strings.h"
  
  #include "ap_config.h"
  #include "httpd.h"
  #include "http_config.h"
  #include "http_core.h"
  #include "http_log.h"
  #include "http_protocol.h"
  #include "http_request.h"
  
  typedef struct {
      int authoritative;
  } authz_user_config_rec;
  
  static void *create_authz_user_dir_config(apr_pool_t *p, char *d)
  {
      authz_user_config_rec *conf = apr_palloc(p, sizeof(*conf));
  
      conf->authoritative = 1; /* keep the fortress secure by default */
      return conf;
  }
  
  static const command_rec authz_user_cmds[] =
  {
      AP_INIT_FLAG("AuthzUserAuthoritative", ap_set_flag_slot,
                   (void *)APR_OFFSETOF(authz_user_config_rec, authoritative),
                   OR_AUTHCFG,
                   "Set to 'no' to allow access control to be passed along to "
                   "lower modules if the 'require user' or 'require valid-user' "
                   "statement is not met. (default: yes)."),
      {NULL}
  };
  
  module AP_MODULE_DECLARE_DATA authz_user_module;
  
  static int check_user_access(request_rec *r)
  {
      authz_user_config_rec *conf = ap_get_module_config(r->per_dir_config,
                                                         &authz_user_module);
      char *user = r->user;
      int m = r->method_number;
      int method_restricted = 0;
      register int x;
      const char *t, *w;
      const apr_array_header_t *reqs_arr = ap_requires(r);
      require_line *reqs;
  
      /* BUG FIX: tadc, 11-Nov-1995.  If there is no "requires" directive, 
       * then any user will do.
       */
      if (!reqs_arr) {
          return DECLINED;
      }
      reqs = (require_line *)reqs_arr->elts;
  
      for (x = 0; x < reqs_arr->nelts; x++) {
  
          if (!(reqs[x].method_mask & (AP_METHOD_BIT << m))) {
              continue;
          }
  
          /* Note that there are applicable requirements 
           */
          method_restricted |= 1;
  
          t = reqs[x].requirement;
          w = ap_getword_white(r->pool, &t);
          if (!strcmp(w, "valid-user")) {
              return OK;
          }
          if (!strcmp(w, "user")) {
              /* And note that there are applicable requirements 
               * which we consider ourselves the owner of.
               */
              method_restricted |= 2;
              while (t[0]) {
                  w = ap_getword_conf(r->pool, &t);
                  if (!strcmp(user, w)) {
                      return OK;
                  }
              }
          }
      }
  
      if (method_restricted == 0) {
          /* no applicable requirements at all */
          return DECLINED;
      }
      /* There are require methods which we do not
       * understand. 
       */
      if ((method_restricted & 2) == 0) {
          /* no requirements of which we consider ourselves
           * the owner.
           */
          return DECLINED;
      }
  
      if (!conf->authoritative) {
          return DECLINED;
      }
  
      ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                    "access to %s failed, reason: user '%s' does not meet "
                    "'require'ments for user/valid-user to be allowed access",
                    r->uri, user);
          
      ap_note_basic_auth_failure(r);
      return HTTP_UNAUTHORIZED;
  }
  
  static void register_hooks(apr_pool_t *p)
  {
      ap_hook_auth_checker(check_user_access, NULL, NULL, APR_HOOK_MIDDLE);
  }
  
  module AP_MODULE_DECLARE_DATA authz_user_module =
  {
      STANDARD20_MODULE_STUFF,
      create_authz_user_dir_config, /* dir config creater */
      NULL,                         /* dir merger --- default is to override */
      NULL,                         /* server config */
      NULL,                         /* merge server config */
      authz_user_cmds,              /* command apr_table_t */
      register_hooks                /* register hooks */
  };
  
  
  

Re: cvs commit: httpd-2.0/modules/aaa

Posted by Justin Erenkrantz <je...@apache.org>.
On Tue, Sep 10, 2002 at 08:51:09AM +0200, Graham Leggett wrote:
> I don't see the auth_ldap stuff included - is it on the cards to be part 
> of the rewrite?

Yeah, ldap is kind of on the radar screen, but it can keep using the
same external auth API (none of the external APIs changed - just how
the aaa/ directory is structured and how our default modules behave).
So, it isn't urgent to change auth_ldap right now.

I just checked in the provider rewrite (not complete - can't do
multiple providers), but functional enough so that we should take
stock of where we are before going further.

The LDAP code fits squarely in the provider section - it should be
able to expose itself via the authn_provider structures and then
mod_auth_basic (and perhaps mod_auth_digest) can use ldap.

I probably want to see the ldap code land in aaa/ldap/ as I'm not
100% sold on cluttering up the aaa/ directory more.  

The other thing is that I bet the ldap code could be greatly
simplified by using the new reslist code in apr-util.  -- justin

Re: cvs commit: httpd-2.0/modules/aaa mod_auth_basic.c mod_authn_anon.c mod_authn_dbm.c mod_authn_default.c mod_authn_file.c mod_authz_dbm.c mod_authz_default.c mod_authz_groupfile.c mod_authz_host.c mod_authz_user.c config.m4 mod_auth_digest.c NWGNUauthanon NWGNUauthdbm mod_access.c mod_access.dsp mod_access.exp mod_auth.c mod_auth.dsp mod_auth.exp mod_auth_anon.c mod_auth_anon.dsp mod_auth_anon.exp mod_auth_dbm.c mod_auth_dbm.dsp mod_auth_dbm.exp

Posted by Graham Leggett <mi...@sharp.fm>.
jerenkrantz@apache.org wrote:

>   Stage #1 of the aaa rewrite - refactoring modules.
>   
>   All modules are reorganized under the following scheme:
>   - mod_auth_*:   Front-end (basic, digest)
>   - mod_authn_*:  Authentication (anon, dbm, default, file)
>   - mod_authz_*:  Authorization (dbm, default, groupfile, host, user)
>   
>   This passes the httpd-test suite when it accounts for the renaming of
>   aaa modules.

I don't see the auth_ldap stuff included - is it on the cards to be part 
of the rewrite?

Regards,
Graham
-- 
-----------------------------------------
minfrin@sharp.fm		"There's a moon
					over Bourbon Street
						tonight..."