httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Tony Sanders <sand...@bsdi.com>
Subject Apache module for system database-based authentication
Date Thu, 11 Jul 1996 21:35:42 GMT
That is, it uses /etc/passwd and /etc/group.  This is useful for
building private webs.

To enable it you add:
        AuthSYSPWEnable enable
to the appropriate config file (usually access.conf).
[suggestions in this area are welcome, I wasn't sure how to do a boolean
without having to write more code than it warrented]

Then you can do the standard things like:
    require user root sanders
    require group admin

I'm calling it mod_auth_syspw.c for now.  I'm posting it here
as a call for comments and I would also like to donate it back
to the Apache group so you are free to use it.

This is currently only lightly tested, after I gather any feedback
and get more testing on it I'll update the list if any changes are
required.

Anyway, feel free to use it if it would be useful to you.  I would
also appreciate knowing if there is already something else like this
available.

PORTING NOTES: you'll need a getgrouplist(), if you don't have one
it's in 4.4BSD-lite.

------- mod_auth_syspw.c -----

/* ====================================================================
 * Copyright (c) 1996 The Apache Group.  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. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the Apache Group
 *    for use in the Apache HTTP server project (http://www.apache.org/)."
 *
 * 4. The names "Apache Server" and "Apache Group" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission.
 *
 * 5. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the Apache Group
 *    for use in the Apache HTTP server project (http://www.apache.org/)."
 *
 * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``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 GROUP OR
 * IT'S 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 Group and was originally based
 * on public domain software written at the National Center for
 * Supercomputing Applications, University of Illinois, Urbana-Champaign.
 * For more information on the Apache Group and the Apache HTTP server
 * project, please see <http://www.apache.org/>.
 *
 */


/*
 * mod_auth_syspw: Authentication based on system password database.
 *                 This is intended for use in private webs.
 * 
 * Original work by Tony Sanders <sanders@earth.com>
 * 
 * mod_auth_syspw was based on mod_auth_db.
 * 
 */

#include "httpd.h"
#include "http_config.h"
#include "http_core.h"
#include "http_log.h"
#include "http_protocol.h"
#include <sys/types.h>
#include <sys/param.h>
#include <unistd.h>
#include <pwd.h>
#include <grp.h>

typedef struct  {
    char *auth_syspw_enabled;
} syspw_auth_config_rec;

void *create_syspw_auth_dir_config (pool *p, char *d)
{
    return pcalloc (p, sizeof(syspw_auth_config_rec));
}

command_rec syspw_auth_cmds[] = {
{ "AuthSYSPWEnable", set_string_slot,
    (void*)XtOffsetOf(syspw_auth_config_rec, auth_syspw_enabled),
    OR_AUTHCFG, TAKE1, NULL },
{ NULL }
};

module syspw_auth_module;

int syspw_authenticate_basic_user (request_rec *r)
{
    syspw_auth_config_rec *sec =
      (syspw_auth_config_rec *)get_module_config (r->per_dir_config,
						&syspw_auth_module);
    conn_rec *c = r->connection;
    char *sent_pw;
    char errstr[MAX_STRING_LEN];
    struct passwd *p;
    int res;
    
    if ((res = get_basic_auth_pw (r, &sent_pw)))
        return res;
    
    if (!sec->auth_syspw_enabled)
        return DECLINED;
	
    p = getpwnam(c->user);
    if (p == NULL) {
        sprintf(errstr,"SYSPW user %s does not exist", c->user);
	log_reason (errstr, r->filename, r);
	note_basic_auth_failure (r);
	return AUTH_REQUIRED;
    }

    if (strcmp(p->pw_passwd, "") == 0)		/* null password */
	return OK;

    if (strcmp(p->pw_passwd, "*") == 0) {
        sprintf(errstr,"user %s: cannot login",c->user);
	log_reason (errstr, r->uri, r);
	note_basic_auth_failure (r);
	return AUTH_REQUIRED;
    }

    if (strcmp(p->pw_passwd,(char *)crypt(sent_pw,p->pw_passwd)) != 0) {
        sprintf(errstr,"user %s: password mismatch",c->user);
	log_reason (errstr, r->uri, r);
	note_basic_auth_failure (r);
	return AUTH_REQUIRED;
    }

    return OK;
}
    
/* Checking ID */
    
int syspw_check_auth(request_rec *r) {
    syspw_auth_config_rec *sec =
      (syspw_auth_config_rec *)get_module_config (r->per_dir_config,
						&syspw_auth_module);
    char *user = r->connection->user;
    int m = r->method_number;		/* GET, PUT, etc */
    char errstr[MAX_STRING_LEN];

    /* holds the information for the user in question */
    struct passwd *p;
    gid_t ugroups[NGROUPS];
    int ngroups = NGROUPS;
    
    array_header *reqs_arr = requires (r);
    require_line *reqs = reqs_arr ? (require_line *)reqs_arr->elts : NULL;

    register int x;	/* interates through the requirements */
    char *t;		/* the list of requirements */
    char *w;		/* a "word" from that list, usage varies */

    /* decline the request if we are not enabled */
    if (!sec->auth_syspw_enabled)
	return DECLINED;

    /* no require directives means anything is OK */
    if (!reqs_arr)
	return OK;

    /* get password and group information for user */
    p = getpwnam(user);
    if (p == NULL) {
        sprintf(errstr,"SYSPW user %s does not exist", user);
	log_reason (errstr, r->filename, r);
	note_basic_auth_failure (r);
	return AUTH_REQUIRED;
    }
    /* an error here would indicate ngroups overflow, we don't care */
    (void) getgrouplist(user, p->pw_gid, &ugroups, &ngroups);

    /* check user privs against the reqs array */
    for (x=0; x < reqs_arr->nelts; x++) {

	/* does this reqs apply to the method being used? */
	if (! (reqs[x].method_mask & (1 << m)))
	    continue;

	t = reqs[x].requirement;

	/* look for requirements (valid-user, user, or group) */
	w = getword(r->pool, &t, ' ');

	/* if valid-user then we are OK */
	if (!strcmp(w,"valid-user"))
	    return OK;

	/* check for user name match against reqs list */
	if(!strcmp(w,"user")) {
	    while(*t) {
		w = getword_conf (r->pool, &t);
		if(!strcmp(user,w))
		    return OK;
	    }
	}

	/* check to see if user is in specified group(s) */
	if (!strcmp(w,"group")) {
	    int i;
	    struct group *g;

	    while (*t) {
		/* w is the next group to check from the require list (t) */
		w = getword(r->pool, &t, ' ');
		if (g = getgrnam(w))		/* ignore invalid groups */
		    for (i = 0; i < ngroups; i++)
			if (g->gr_gid == ugroups[i])
			    return OK;
	    }

	    sprintf(errstr,"user %s not in right group",user);
	    log_reason (errstr, r->filename, r);
	    note_basic_auth_failure(r);
	    return AUTH_REQUIRED;
	}
    }
    
    return DECLINED;
}

module syspw_auth_module = {
   STANDARD_MODULE_STUFF,
   NULL,			/* initializer */
   create_syspw_auth_dir_config,/* dir config creater */
   NULL,			/* dir merger --- default is to override */
   NULL,			/* server config */
   NULL,			/* merge server config */
   syspw_auth_cmds,		/* command table */
   NULL,			/* handlers */
   NULL,			/* filename translation */
   syspw_authenticate_basic_user,/* check_user_id */
   syspw_check_auth,		/* check auth */
   NULL,			/* check access */
   NULL,			/* type_checker */
   NULL,			/* fixups */
   NULL				/* logger */
};

Mime
View raw message