home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 25 / CDROM25.iso / Share / linux / apache / contrib / modules / mod_auth_external.c next >
Encoding:
C/C++ Source or Header  |  1998-06-11  |  10.1 KB  |  379 lines

  1. /* ====================================================================
  2.  * Copyright (c) 1995 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.
  24.  *
  25.  * 5. Redistributions of any form whatsoever must retain the following
  26.  *    acknowledgment:
  27.  *    "This product includes software developed by the Apache Group
  28.  *    for use in the Apache HTTP server project (http://www.apache.org/)."
  29.  *
  30.  * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
  31.  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  32.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  33.  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
  34.  * IT'S CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  35.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  36.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  37.  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  38.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  39.  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  40.  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  41.  * OF THE POSSIBILITY OF SUCH DAMAGE.
  42.  * ====================================================================
  43.  *
  44.  * This software consists of voluntary contributions made by many
  45.  * individuals on behalf of the Apache Group and was originally based
  46.  * on public domain software written at the National Center for
  47.  * Supercomputing Applications, University of Illinois, Urbana-Champaign.
  48.  * For more information on the Apache Group and the Apache HTTP server
  49.  * project, please see <http://www.apache.org/>.
  50.  *
  51.  */
  52.  
  53. /********
  54.  Add to Configuration file:
  55.     Module external_auth_module    mod_auth_external.o
  56.  
  57. Add to server configuration file:
  58.     AddExternalAuth <keyword> <path-to-authenticator>
  59.     AddExternalGroup <keyword> <path-to-group-checker>
  60.  
  61. Usage in auth config files:
  62.  
  63.     AuthExternal <keyword>
  64.     AuthExternal afs
  65.     GroupExternal <keyword>
  66.     GroupExternal unix
  67.  
  68. AuthExternals are passed the userid and passwd in the USER and PASS 
  69. environment variables, and return a success code of 0 to indicate
  70. successful authentication. Non-zero result indicates either a failure to 
  71. authenticate, or a failure to execute the authenticator.
  72.  
  73. GroupExternals are passed the userid and desired group in the USER and GROUP
  74. environment variables, and return a success code of 0 to indicate successful
  75. authentication. Non-zero result indicates non-membersip or a failure
  76. to execute the group checker.
  77.  
  78. The need for this module arises from difficulties I have had linking 
  79. apache with other libraries (such as AFS, and database access libs).
  80.  
  81. Comments/questions/etc. to nneul@umr.edu
  82.  
  83. ********/
  84.  
  85. /*
  86.  * External authentication module by nneul@umr.edu
  87.  */
  88.  
  89. #include "httpd.h"
  90. #include "http_config.h"
  91. #include "http_core.h"
  92. #include "http_log.h"
  93. #include "http_protocol.h"
  94. #include <sys/wait.h>
  95.  
  96. /*
  97.  * Structure for the module itself
  98.  */
  99.  
  100. module external_auth_module;
  101.  
  102. /*
  103.  *  Data types for per-dir and server configuration
  104.  */
  105. typedef struct
  106. {
  107.     char *auth_extname;
  108.     char *group_extname;
  109. } extauth_dir_config_rec;
  110.  
  111. typedef struct 
  112. {
  113.     table *auth_externals;
  114.     table *group_externals;
  115. } extauth_server_config_rec;
  116.  
  117. /*
  118.  * Creators for per-dir and server configurations
  119.  */
  120.  
  121. void *create_extauth_dir_config (pool *p, char *d)
  122. {
  123.     return pcalloc (p, sizeof(extauth_dir_config_rec));
  124. }
  125.  
  126.  
  127. void *create_extauth_server_config ( pool *p, server_rec *s)
  128. {
  129.     extauth_server_config_rec *scr;
  130.  
  131.     scr = (extauth_server_config_rec *) palloc(p,
  132.         sizeof(extauth_server_config_rec) );
  133.  
  134.     scr->auth_externals = make_table(p, 4);
  135.     scr->group_externals = make_table(p, 4);
  136.  
  137.     return (void *)scr;
  138. }
  139.  
  140. /*
  141.  * Handler for a server config line - add a external type to the
  142.  * server configuration
  143.  */
  144.  
  145. char *add_extauth(cmd_parms *cmd, void *dummy, char *keyword, char *path)
  146. {
  147.     extauth_server_config_rec *sc_rec;
  148.  
  149.     sc_rec = get_module_config( cmd->server->module_config,
  150.         &external_auth_module);
  151.  
  152.     table_set ( sc_rec->auth_externals, keyword, path );
  153.  
  154.     return NULL;
  155. }
  156.  
  157. /*
  158.  * Handler for a server config line - add a external type to the
  159.  * server configuration
  160.  */
  161.  
  162. char *add_extgroup(cmd_parms *cmd, void *dummy, char *keyword, char *path)
  163. {
  164.     extauth_server_config_rec *sc_rec;
  165.  
  166.     sc_rec = get_module_config( cmd->server->module_config,
  167.         &external_auth_module);
  168.  
  169.     table_set ( sc_rec->group_externals, keyword, path );
  170.  
  171.     return NULL;
  172. }
  173.  
  174.  
  175. /*
  176.  * Commands that this module can handle
  177.  */
  178.  
  179. command_rec extauth_cmds[] = {
  180.     { "AuthExternal", set_string_slot, 
  181.     (void*)XtOffsetOf(extauth_dir_config_rec,auth_extname),
  182.     OR_AUTHCFG, TAKE1, "a keyword indicating which authenticator to use" },
  183.  
  184.     { "AddExternalAuth", add_extauth, NULL, RSRC_CONF, TAKE2,
  185.     "a keyword followed by a path to the authenticator program" },
  186.  
  187.     { "GroupExternal", set_string_slot, 
  188.     (void*)XtOffsetOf(extauth_dir_config_rec,group_extname),
  189.     OR_AUTHCFG, TAKE1, "a keyword indicating which group checker to use" },
  190.  
  191.     { "AddExternalGroup", add_extgroup, NULL, RSRC_CONF, TAKE2,
  192.     "a keyword followed by a path to the group check program" },
  193.     { NULL }
  194. };
  195.  
  196.  
  197.  
  198.  
  199. /*
  200.  * Authenticate a user
  201.  */
  202.  
  203. int extauth_basic_user (request_rec *r)
  204. {
  205.     extauth_dir_config_rec *dir_config_rec =
  206.         (extauth_dir_config_rec *)get_module_config (r->per_dir_config,
  207.         &external_auth_module);
  208.  
  209.     extauth_server_config_rec *server_config_rec =
  210.         (extauth_server_config_rec *)get_module_config (r->server->module_config,
  211.         &external_auth_module);
  212.  
  213.     char *sent_pw;
  214.  
  215.     char errstr[MAX_STRING_LEN];
  216.     char env_user[MAX_STRING_LEN];
  217.     char env_pass[MAX_STRING_LEN];
  218.     int res, code;
  219.     char *external, *extname, *extpath;
  220.  
  221.     conn_rec *c = r->connection;
  222.  
  223.     /* Get the password, exit if can't get */
  224.     if ((res = get_basic_auth_pw (r, &sent_pw)))
  225.         return res;
  226.  
  227.     /* Extract which external was chosen */
  228.     extname = dir_config_rec->auth_extname;
  229.  
  230.     /* Check if we are supposed to handle this authentication */
  231.     if ( !extname )
  232.     {
  233.         return DECLINED;
  234.     }
  235.  
  236.  
  237.     /* Get the path associated with that external */
  238.     if (extpath = table_get (server_config_rec->auth_externals, extname))
  239.     {
  240.         /* Set envir vars for the userid and password */
  241.         sprintf(env_user, "%s=%s", "USER", c->user);
  242.         sprintf(env_pass, "%s=%s", "PASS", sent_pw);
  243.         putenv(env_user);
  244.         putenv(env_pass);
  245.  
  246.         code = system(extpath);
  247.  
  248.         if(code)
  249.         {
  250.             sprintf(errstr, "External Auth (%s): Failed (%d) for user %s pass %s", 
  251.                 extname, code, c->user, sent_pw);
  252.             log_reason(errstr, r->filename, r);
  253.             note_basic_auth_failure(r);
  254.             return AUTH_REQUIRED;
  255.         }
  256.         return OK;
  257.     }
  258.     else
  259.     {
  260.         sprintf(errstr, "External Auth: Invalid external keyword (%s)", extname);
  261.         log_reason(errstr, r->filename, r);
  262.         note_basic_auth_failure(r);
  263.         return AUTH_REQUIRED;
  264.     }
  265.  
  266.  
  267.     /* shouldn't get here */
  268.     return OK;
  269. }
  270.  
  271.  
  272. int extauth_check_auth(request_rec *r) 
  273. {
  274.     extauth_dir_config_rec *dir_config_rec =
  275.         (extauth_dir_config_rec *)get_module_config (r->per_dir_config,
  276.         &external_auth_module);
  277.  
  278.     extauth_server_config_rec *server_config_rec =
  279.         (extauth_server_config_rec *)get_module_config (r->server->module_config,
  280.         &external_auth_module);
  281.  
  282.     conn_rec *c = r->connection;
  283.  
  284.     int m = r->method_number;
  285.     char errstr[MAX_STRING_LEN];
  286.  
  287.     char env_user[MAX_STRING_LEN];
  288.     char env_group[MAX_STRING_LEN];
  289.     int res, code;
  290.     char *external, *extname, *extpath;
  291.     
  292.     array_header *reqs_arr = requires (r);
  293.     require_line *reqs = reqs_arr ? (require_line *)reqs_arr->elts : NULL;
  294.  
  295.     int x;
  296.     char *t, *w;
  297.  
  298.     /* Extract which external was chosen */
  299.     extname = dir_config_rec->group_extname;
  300.  
  301.     /* Check if we are supposed to handle this authentication */
  302.     if ( !extname )
  303.     {
  304.         return DECLINED;
  305.     }
  306.  
  307.     if (!reqs_arr) return DECLINED;
  308.     
  309.     for(x=0; x < reqs_arr->nelts; x++) 
  310.     {
  311.         if (! (reqs[x].method_mask & (1 << m))) continue;
  312.     
  313.         t = reqs[x].requirement;
  314.         w = getword(r->pool, &t, ' ');
  315.     
  316.             if(!strcmp(w,"valid-user"))
  317.                 return OK;
  318.             if(!strcmp(w,"user")) 
  319.         {
  320.                 while(t[0]) 
  321.             {
  322.                     w = getword_conf (r->pool, &t);
  323.                     if(!strcmp(c->user,w))
  324.                 return OK;
  325.             }
  326.         }
  327.         else if( !strcmp(w,"group") ) 
  328.         {
  329.             while(t[0]) 
  330.             {
  331.                 w = getword(r->pool, &t, ' ');
  332.  
  333.     /* Get the path associated with that external */
  334.                 if (extpath = table_get (server_config_rec->group_externals, extname))
  335.                 {
  336.                     /* Set envir vars for the userid and password */
  337.                     sprintf(env_user, "%s=%s", "USER", c->user);
  338.                     sprintf(env_group, "%s=%s", "GROUP", w);
  339.                     putenv(env_user);
  340.                     putenv(env_group);
  341.  
  342.                     code = system(extpath);
  343.                     if ( !code ) return OK;
  344.                 }
  345.                 else
  346.                 {
  347.                     sprintf(errstr, "External Group: Invalid external keyword (%s)", extname);
  348.                     log_reason(errstr, r->filename, r);
  349.                     note_basic_auth_failure(r);
  350.                     return AUTH_REQUIRED;
  351.                 }
  352.             }
  353.         }
  354.     }
  355.     
  356.     return DECLINED;
  357. }
  358.  
  359.  
  360.  
  361.  
  362. module external_auth_module = {
  363.     STANDARD_MODULE_STUFF,
  364.         NULL,            /* initializer */
  365.     create_extauth_dir_config,    /* dir config creater */
  366.     NULL,            /* dir merger --- default is to override */
  367.     create_extauth_server_config,    /* server config */
  368.     NULL,            /* merge server config */
  369.     extauth_cmds,        /* command table */
  370.     NULL,            /* handlers */
  371.     NULL,            /* filename translation */
  372.     extauth_basic_user,    /* check_user_id */
  373.     extauth_check_auth,            /* check auth */
  374.     NULL,            /* check access */
  375.     NULL,            /* type_checker */
  376.     NULL,            /* fixups */
  377.     NULL                /* logger */
  378. };
  379.