home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1999 April / PCO0499.ISO / filesbbs / os2 / apach134.arj / APACH134.ZIP / src / modules / standard / mod_auth_dbm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-01-01  |  9.9 KB  |  328 lines

  1. /* ====================================================================
  2.  * Copyright (c) 1995-1999 The Apache Group.  All rights reserved.
  3.  *
  4.  * Redistribution and use in source and binary forms, with or without
  5.  * modification, are permitted provided that the following conditions
  6.  * are met:
  7.  *
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer. 
  10.  *
  11.  * 2. Redistributions in binary form must reproduce the above copyright
  12.  *    notice, this list of conditions and the following disclaimer in
  13.  *    the documentation and/or other materials provided with the
  14.  *    distribution.
  15.  *
  16.  * 3. All advertising materials mentioning features or use of this
  17.  *    software must display the following acknowledgment:
  18.  *    "This product includes software developed by the Apache Group
  19.  *    for use in the Apache HTTP server project (http://www.apache.org/)."
  20.  *
  21.  * 4. The names "Apache Server" and "Apache Group" must not be used to
  22.  *    endorse or promote products derived from this software without
  23.  *    prior written permission. For written permission, please contact
  24.  *    apache@apache.org.
  25.  *
  26.  * 5. Products derived from this software may not be called "Apache"
  27.  *    nor may "Apache" appear in their names without prior written
  28.  *    permission of the Apache Group.
  29.  *
  30.  * 6. Redistributions of any form whatsoever must retain the following
  31.  *    acknowledgment:
  32.  *    "This product includes software developed by the Apache Group
  33.  *    for use in the Apache HTTP server project (http://www.apache.org/)."
  34.  *
  35.  * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
  36.  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  37.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  38.  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
  39.  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  41.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  42.  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  43.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  44.  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  45.  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  46.  * OF THE POSSIBILITY OF SUCH DAMAGE.
  47.  * ====================================================================
  48.  *
  49.  * This software consists of voluntary contributions made by many
  50.  * individuals on behalf of the Apache Group and was originally based
  51.  * on public domain software written at the National Center for
  52.  * Supercomputing Applications, University of Illinois, Urbana-Champaign.
  53.  * For more information on the Apache Group and the Apache HTTP server
  54.  * project, please see <http://www.apache.org/>.
  55.  *
  56.  */
  57.  
  58. /*
  59.  * http_auth: authentication
  60.  * 
  61.  * Rob McCool & Brian Behlendorf.
  62.  * 
  63.  * Adapted to Apache by rst.
  64.  *
  65.  * dirkx - Added Authoritative control to allow passing on to lower  
  66.  *         modules if and only if the user-id is not known to this
  67.  *         module. A known user with a faulty or absent password still
  68.  *         causes an AuthRequired. The default is 'Authoritative', i.e.
  69.  *         no control is passed along.
  70.  */
  71.  
  72. #include "httpd.h"
  73. #include "http_config.h"
  74. #include "http_core.h"
  75. #include "http_log.h"
  76. #include "http_protocol.h"
  77. #include <ndbm.h>
  78.  
  79. /*
  80.  * Module definition information - the part between the -START and -END
  81.  * lines below is used by Configure. This could be stored in a separate
  82.  * instead.
  83.  *
  84.  * MODULE-DEFINITION-START
  85.  * Name: dbm_auth_module
  86.  * ConfigStart
  87.     . ./helpers/find-dbm-lib
  88.  * ConfigEnd
  89.  * MODULE-DEFINITION-END
  90.  */
  91.  
  92. typedef struct {
  93.  
  94.     char *auth_dbmpwfile;
  95.     char *auth_dbmgrpfile;
  96.     int auth_dbmauthoritative;
  97.  
  98. } dbm_auth_config_rec;
  99.  
  100. static void *create_dbm_auth_dir_config(pool *p, char *d)
  101. {
  102.     dbm_auth_config_rec *sec
  103.     = (dbm_auth_config_rec *) ap_pcalloc(p, sizeof(dbm_auth_config_rec));
  104.  
  105.     sec->auth_dbmpwfile = NULL;
  106.     sec->auth_dbmgrpfile = NULL;
  107.     sec->auth_dbmauthoritative = 1;    /* fortress is secure by default */
  108.  
  109.     return sec;
  110. }
  111.  
  112. static const char *set_dbm_slot(cmd_parms *cmd, void *offset, char *f, char *t)
  113. {
  114.     if (!t || strcmp(t, "dbm"))
  115.     return DECLINE_CMD;
  116.  
  117.     return ap_set_file_slot(cmd, offset, f);
  118. }
  119.  
  120. static const command_rec dbm_auth_cmds[] =
  121. {
  122.     {"AuthDBMUserFile", ap_set_file_slot,
  123.      (void *) XtOffsetOf(dbm_auth_config_rec, auth_dbmpwfile),
  124.      OR_AUTHCFG, TAKE1, NULL},
  125.     {"AuthDBMGroupFile", ap_set_file_slot,
  126.      (void *) XtOffsetOf(dbm_auth_config_rec, auth_dbmgrpfile),
  127.      OR_AUTHCFG, TAKE1, NULL},
  128.     {"AuthUserFile", set_dbm_slot,
  129.      (void *) XtOffsetOf(dbm_auth_config_rec, auth_dbmpwfile),
  130.      OR_AUTHCFG, TAKE12, NULL},
  131.     {"AuthGroupFile", set_dbm_slot,
  132.      (void *) XtOffsetOf(dbm_auth_config_rec, auth_dbmgrpfile),
  133.      OR_AUTHCFG, TAKE12, NULL},
  134.     {"AuthDBMAuthoritative", ap_set_flag_slot,
  135.      (void *) XtOffsetOf(dbm_auth_config_rec, auth_dbmauthoritative),
  136.      OR_AUTHCFG, FLAG, "Set to 'no' to allow access control to be passed along to lower modules, if the UserID is not known in this module"},
  137.     {NULL}
  138. };
  139.  
  140. module dbm_auth_module;
  141.  
  142. static char *get_dbm_pw(request_rec *r, char *user, char *auth_dbmpwfile)
  143. {
  144.     DBM *f;
  145.     datum d, q;
  146.     char *pw = NULL;
  147.  
  148.     q.dptr = user;
  149. #ifndef NETSCAPE_DBM_COMPAT
  150.     q.dsize = strlen(q.dptr);
  151. #else
  152.     q.dsize = strlen(q.dptr) + 1;
  153. #endif
  154.  
  155.  
  156.     if (!(f = dbm_open(auth_dbmpwfile, O_RDONLY, 0664))) {
  157.     ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
  158.             "could not open dbm auth file: %s", auth_dbmpwfile);
  159.     return NULL;
  160.     }
  161.  
  162.     d = dbm_fetch(f, q);
  163.  
  164.     if (d.dptr) {
  165.     pw = ap_palloc(r->pool, d.dsize + 1);
  166.     strncpy(pw, d.dptr, d.dsize);
  167.     pw[d.dsize] = '\0';    /* Terminate the string */
  168.     }
  169.  
  170.     dbm_close(f);
  171.     return pw;
  172. }
  173.  
  174. /* We do something strange with the group file.  If the group file
  175.  * contains any : we assume the format is
  176.  *      key=username value=":"groupname [":"anything here is ignored]
  177.  * otherwise we now (0.8.14+) assume that the format is
  178.  *      key=username value=groupname
  179.  * The first allows the password and group files to be the same 
  180.  * physical DBM file;   key=username value=password":"groupname[":"anything]
  181.  *
  182.  * mark@telescope.org, 22Sep95
  183.  */
  184.  
  185. static char *get_dbm_grp(request_rec *r, char *user, char *auth_dbmgrpfile)
  186. {
  187.     char *grp_data = get_dbm_pw(r, user, auth_dbmgrpfile);
  188.     char *grp_colon;
  189.     char *grp_colon2;
  190.  
  191.     if (grp_data == NULL)
  192.     return NULL;
  193.  
  194.     if ((grp_colon = strchr(grp_data, ':')) != NULL) {
  195.     grp_colon2 = strchr(++grp_colon, ':');
  196.     if (grp_colon2)
  197.         *grp_colon2 = '\0';
  198.     return grp_colon;
  199.     }
  200.     return grp_data;
  201. }
  202.  
  203. static int dbm_authenticate_basic_user(request_rec *r)
  204. {
  205.     dbm_auth_config_rec *sec =
  206.     (dbm_auth_config_rec *) ap_get_module_config(r->per_dir_config,
  207.                           &dbm_auth_module);
  208.     conn_rec *c = r->connection;
  209.     const char *sent_pw;
  210.     char *real_pw, *colon_pw;
  211.     int res;
  212.  
  213.     if ((res = ap_get_basic_auth_pw(r, &sent_pw)))
  214.     return res;
  215.  
  216.     if (!sec->auth_dbmpwfile)
  217.     return DECLINED;
  218.  
  219.     if (!(real_pw = get_dbm_pw(r, c->user, sec->auth_dbmpwfile))) {
  220.     if (!(sec->auth_dbmauthoritative))
  221.         return DECLINED;
  222.     ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
  223.             "DBM user %s not found: %s", c->user, r->filename);
  224.     ap_note_basic_auth_failure(r);
  225.     return AUTH_REQUIRED;
  226.     }
  227.     /* Password is up to first : if exists */
  228.     colon_pw = strchr(real_pw, ':');
  229.     if (colon_pw)
  230.     *colon_pw = '\0';
  231.     /* anyone know where the prototype for crypt is? */
  232.     if (strcmp(real_pw, (char *) crypt(sent_pw, real_pw))) {
  233.     ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
  234.             "user %s: password mismatch: %s", c->user, r->uri);
  235.     ap_note_basic_auth_failure(r);
  236.     return AUTH_REQUIRED;
  237.     }
  238.     return OK;
  239. }
  240.  
  241. /* Checking ID */
  242.  
  243. static int dbm_check_auth(request_rec *r)
  244. {
  245.     dbm_auth_config_rec *sec =
  246.     (dbm_auth_config_rec *) ap_get_module_config(r->per_dir_config,
  247.                           &dbm_auth_module);
  248.     char *user = r->connection->user;
  249.     int m = r->method_number;
  250.  
  251.     const array_header *reqs_arr = ap_requires(r);
  252.     require_line *reqs = reqs_arr ? (require_line *) reqs_arr->elts : NULL;
  253.  
  254.     register int x;
  255.     const char *t;
  256.     char *w;
  257.  
  258.     if (!sec->auth_dbmgrpfile)
  259.     return DECLINED;
  260.     if (!reqs_arr)
  261.     return DECLINED;
  262.  
  263.     for (x = 0; x < reqs_arr->nelts; x++) {
  264.  
  265.     if (!(reqs[x].method_mask & (1 << m)))
  266.         continue;
  267.  
  268.     t = reqs[x].requirement;
  269.     w = ap_getword_white(r->pool, &t);
  270.  
  271.     if (!strcmp(w, "group") && sec->auth_dbmgrpfile) {
  272.         const char *orig_groups, *groups;
  273.         char *v;
  274.  
  275.         if (!(groups = get_dbm_grp(r, user, sec->auth_dbmgrpfile))) {
  276.         if (!(sec->auth_dbmauthoritative))
  277.             return DECLINED;
  278.         ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
  279.                 "user %s not in DBM group file %s: %s",
  280.                 user, sec->auth_dbmgrpfile, r->filename);
  281.         ap_note_basic_auth_failure(r);
  282.         return AUTH_REQUIRED;
  283.         }
  284.         orig_groups = groups;
  285.         while (t[0]) {
  286.         w = ap_getword_white(r->pool, &t);
  287.         groups = orig_groups;
  288.         while (groups[0]) {
  289.             v = ap_getword(r->pool, &groups, ',');
  290.             if (!strcmp(v, w))
  291.             return OK;
  292.         }
  293.         }
  294.         ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r,
  295.             "user %s not in right group: %s",
  296.             user, r->filename);
  297.         ap_note_basic_auth_failure(r);
  298.         return AUTH_REQUIRED;
  299.     }
  300.     }
  301.  
  302.     return DECLINED;
  303. }
  304.  
  305.  
  306. module dbm_auth_module =
  307. {
  308.     STANDARD_MODULE_STUFF,
  309.     NULL,            /* initializer */
  310.     create_dbm_auth_dir_config,    /* dir config creater */
  311.     NULL,            /* dir merger --- default is to override */
  312.     NULL,            /* server config */
  313.     NULL,            /* merge server config */
  314.     dbm_auth_cmds,        /* command table */
  315.     NULL,            /* handlers */
  316.     NULL,            /* filename translation */
  317.     dbm_authenticate_basic_user,    /* check_user_id */
  318.     dbm_check_auth,        /* check auth */
  319.     NULL,            /* check access */
  320.     NULL,            /* type_checker */
  321.     NULL,            /* fixups */
  322.     NULL,            /* logger */
  323.     NULL,            /* header parser */
  324.     NULL,            /* child_init */
  325.     NULL,            /* child_exit */
  326.     NULL            /* post read-request */
  327. };
  328.