You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by bn...@apache.org on 2005/11/30 05:23:08 UTC
svn commit: r349875 - in /httpd/httpd/branches/authz-dev:
include/http_core.h modules/aaa/mod_auth.h modules/aaa/mod_authz_host.c
server/core.c
Author: bnicholes
Date: Tue Nov 29 20:22:48 2005
New Revision: 349875
URL: http://svn.apache.org/viewcvs?rev=349875&view=rev
Log:
first cut at moving the require directive out of mod_core and implementing it as a provider vector.
Modified:
httpd/httpd/branches/authz-dev/include/http_core.h
httpd/httpd/branches/authz-dev/modules/aaa/mod_auth.h
httpd/httpd/branches/authz-dev/modules/aaa/mod_authz_host.c
httpd/httpd/branches/authz-dev/server/core.c
Modified: httpd/httpd/branches/authz-dev/include/http_core.h
URL: http://svn.apache.org/viewcvs/httpd/httpd/branches/authz-dev/include/http_core.h?rev=349875&r1=349874&r2=349875&view=diff
==============================================================================
--- httpd/httpd/branches/authz-dev/include/http_core.h (original)
+++ httpd/httpd/branches/authz-dev/include/http_core.h Tue Nov 29 20:22:48 2005
@@ -454,9 +454,9 @@
/* Authentication stuff. Groan... */
int *satisfy; /* for every method one */
- char *ap_auth_type;
- char *ap_auth_name;
- apr_array_header_t *ap_requires;
+ char *ap_auth_type; /* Deprecated see mod_authz_host */
+ char *ap_auth_name; /* Deprecated see mod_authz_host */
+ apr_array_header_t *ap_requires; /* Deprecated see mod_authz_host */
/* Custom response config. These can contain text or a URL to redirect to.
* if response_code_strings is NULL then there are none in the config,
@@ -679,6 +679,18 @@
APR_DECLARE_OPTIONAL_FN(const char *, ap_ident_lookup,
(request_rec *r));
+
+/* ----------------------------------------------------------------------
+ *
+ * authorization values with mod_authz_host
+ */
+
+APR_DECLARE_OPTIONAL_FN(const apr_array_header_t *, authz_host_ap_requires,
+ (request_rec *r));
+/*
+APR_DECLARE_OPTIONAL_FN(const char *, authz_host_ap_auth_type, (request_rec *r));
+APR_DECLARE_OPTIONAL_FN(const char *, authz_host_ap_auth_name, (request_rec *r));
+*/
/* ---------------------------------------------------------------------- */
Modified: httpd/httpd/branches/authz-dev/modules/aaa/mod_auth.h
URL: http://svn.apache.org/viewcvs/httpd/httpd/branches/authz-dev/modules/aaa/mod_auth.h?rev=349875&r1=349874&r2=349875&view=diff
==============================================================================
--- httpd/httpd/branches/authz-dev/modules/aaa/mod_auth.h (original)
+++ httpd/httpd/branches/authz-dev/modules/aaa/mod_auth.h Tue Nov 29 20:22:48 2005
@@ -35,10 +35,13 @@
#endif
#define AUTHN_PROVIDER_GROUP "authn"
+#define AUTHZ_PROVIDER_GROUP "authz"
#define AUTHN_DEFAULT_PROVIDER "file"
+#define AUTHZ_DEFAULT_PROVIDER "valid-user"
#define AUTHZ_GROUP_NOTE "authz_group_note"
#define AUTHN_PROVIDER_NAME_NOTE "authn_provider_name"
+#define AUTHZ_PROVIDER_NAME_NOTE "authz_provider_name"
typedef enum {
AUTH_DENIED,
@@ -72,9 +75,36 @@
};
typedef struct {
+ /* Given a username and password, expected to return AUTH_GRANTED
+ * if we can validate this user/password combination.
+ */
+ authn_status (*check_authorization)(request_rec *r);
+} authz_provider;
+
+/* A linked-list of authn providers. */
+typedef struct authz_provider_list authz_provider_list;
+
+struct authz_provider_list {
+ const char *provider_name;
+ const authz_provider *provider;
+ authz_provider_list *next;
+ /** Where the require line is in the config file. */
+ apr_int64_t method_mask;
+ /** The complete string from the command line */
+ char *requirement;
+};
+
+/* Need to add an enum for authz_status. Convert one of the authorization
+ modules to deal with the new require directive.
+*/
+
+
+#if 0
+typedef struct {
/* For a given user, return a hash of all groups the user belongs to. */
apr_hash_t * (*get_user_groups)(request_rec *r, const char *user);
} authz_provider;
+#endif
#ifdef __cplusplus
}
Modified: httpd/httpd/branches/authz-dev/modules/aaa/mod_authz_host.c
URL: http://svn.apache.org/viewcvs/httpd/httpd/branches/authz-dev/modules/aaa/mod_authz_host.c?rev=349875&r1=349874&r2=349875&view=diff
==============================================================================
--- httpd/httpd/branches/authz-dev/modules/aaa/mod_authz_host.c (original)
+++ httpd/httpd/branches/authz-dev/modules/aaa/mod_authz_host.c Tue Nov 29 20:22:48 2005
@@ -35,6 +35,10 @@
#include "http_config.h"
#include "http_log.h"
#include "http_request.h"
+#include "http_protocol.h"
+#include "ap_provider.h"
+
+#include "mod_auth.h"
#if APR_HAVE_NETINET_IN_H
#include <netinet/in.h>
@@ -66,6 +70,8 @@
int order[METHODS];
apr_array_header_t *allows;
apr_array_header_t *denys;
+ apr_array_header_t *ap_requires;
+ authz_provider_list *providers;
} authz_host_dir_conf;
module AP_MODULE_DECLARE_DATA authz_host_module;
@@ -85,6 +91,35 @@
return (void *)conf;
}
+static void *merge_authz_host_dir_config(apr_pool_t *a, void *basev, void *newv)
+{
+ authz_host_dir_conf *base = (authz_host_dir_conf *)basev;
+ authz_host_dir_conf *new = (authz_host_dir_conf *)newv;
+ authz_host_dir_conf *conf;
+
+ /* Create this conf by duplicating the base, replacing elements
+ * (or creating copies for merging) where new-> values exist.
+ */
+ conf = (authz_host_dir_conf *)apr_palloc(a, sizeof(authz_host_dir_conf));
+ memcpy(conf, base, sizeof(authz_host_dir_conf));
+
+ /*
+ if (new->ap_auth_type) {
+ conf->ap_auth_type = new->ap_auth_type;
+ }
+
+ if (new->ap_auth_name) {
+ conf->ap_auth_name = new->ap_auth_name;
+ }
+ */
+
+ if (new->ap_requires) {
+ conf->ap_requires = new->ap_requires;
+ }
+
+ 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;
@@ -159,6 +194,85 @@
return NULL;
}
+/*
+ * Load an authorisation realm into our location configuration, applying the
+ * usual rules that apply to realms.
+ */
+/*
+static const char *set_authname(cmd_parms *cmd, void *mconfig,
+ const char *word1)
+{
+ authz_host_dir_conf *aconfig = (authz_host_dir_conf *)mconfig;
+
+ aconfig->ap_auth_name = ap_escape_quotes(cmd->pool, word1);
+ return NULL;
+}
+*/
+
+/*
+static const char *require(cmd_parms *cmd, void *c_, const char *arg)
+{
+ require_line *r;
+ authz_host_dir_conf *c = c_;
+
+ if (!c->ap_requires) {
+ c->ap_requires = apr_array_make(cmd->pool, 2, sizeof(require_line));
+ }
+
+ r = (require_line *)apr_array_push(c->ap_requires);
+ r->requirement = apr_pstrdup(cmd->pool, arg);
+ r->method_mask = cmd->limited;
+
+ return NULL;
+}
+*/
+
+static const char *add_authz_provider(cmd_parms *cmd, void *config,
+ const char *arg)
+{
+ authz_host_dir_conf *conf = (authz_host_dir_conf*)config;
+ authz_provider_list *newp;
+
+ newp = apr_pcalloc(cmd->pool, sizeof(authz_provider_list));
+ newp->provider_name = apr_pstrdup(cmd->pool, arg);
+ newp->requirement = apr_pstrdup(cmd->pool, arg);
+ newp->method_mask = cmd->limited;
+
+ /* lookup and cache the actual provider now */
+ newp->provider = ap_lookup_provider(AUTHZ_PROVIDER_GROUP,
+ newp->provider_name, "0");
+
+ if (newp->provider == NULL) {
+ /* by the time they use it, the provider should be loaded and
+ registered with us. */
+ return apr_psprintf(cmd->pool,
+ "Unknown Authz provider: %s",
+ newp->provider_name);
+ }
+
+ if (!newp->provider->check_authorization) {
+ /* if it doesn't provide the appropriate function, reject it */
+ return apr_psprintf(cmd->pool,
+ "The '%s' Authz provider is not supported by any of the "
+ "loaded authorization modules", newp->provider_name);
+ }
+
+ /* Add it to the list now. */
+ if (!conf->providers) {
+ conf->providers = newp;
+ }
+ else {
+ authz_provider_list *last = conf->providers;
+
+ while (last->next) {
+ last = last->next;
+ }
+ last->next = newp;
+ }
+
+ return NULL;
+}
+
static char its_an_allow;
static const command_rec authz_host_cmds[] =
@@ -169,8 +283,17 @@
"'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"),
+ AP_INIT_RAW_ARGS("Require", add_authz_provider, NULL, OR_AUTHCFG,
+ "Selects which authenticated users or groups may access a protected space"),
{NULL}
};
+/*
+ AP_INIT_TAKE1("AuthType", ap_set_string_slot,
+ (void*)APR_OFFSETOF(authz_host_dir_conf, ap_auth_type), OR_AUTHCFG,
+ "An HTTP authorization type (e.g., \"Basic\")"),
+ AP_INIT_TAKE1("AuthName", set_authname, NULL, OR_AUTHCFG,
+ "The authentication realm (e.g. \"Members Only\")"),
+*/
static int in_domain(const char *domain, const char *what)
{
@@ -304,17 +427,139 @@
return ret;
}
+static int authorize_user(request_rec *r)
+{
+ authz_host_dir_conf *conf = ap_get_module_config(r->per_dir_config,
+ &authz_host_module);
+ authn_status auth_result;
+ authz_provider_list *current_provider;
+
+ current_provider = conf->providers;
+ do {
+ const authz_provider *provider;
+
+ /* For now, if a provider isn't set, we'll be nice and use the file
+ * provider.
+ */
+ if (!current_provider) {
+ provider = ap_lookup_provider(AUTHZ_PROVIDER_GROUP,
+ AUTHZ_DEFAULT_PROVIDER, "0");
+
+ if (!provider || !provider->check_authorization) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+ "No Authz provider configured");
+ auth_result = AUTH_GENERAL_ERROR;
+ break;
+ }
+ apr_table_setn(r->notes, AUTHZ_PROVIDER_NAME_NOTE, AUTHZ_DEFAULT_PROVIDER);
+ }
+ else {
+ provider = current_provider->provider;
+ apr_table_setn(r->notes, AUTHZ_PROVIDER_NAME_NOTE, current_provider->provider_name);
+ }
+
+
+ auth_result = provider->check_authorization(r);
+
+ apr_table_unset(r->notes, AUTHZ_PROVIDER_NAME_NOTE);
+
+ /* Something occured. Stop checking. */
+ if (auth_result != AUTH_DENIED) {
+ break;
+ }
+
+ /* If we're not really configured for providers, stop now. */
+ if (!conf->providers) {
+ break;
+ }
+
+ current_provider = current_provider->next;
+ } while (current_provider);
+
+ if (auth_result != AUTH_GRANTED) {
+ int return_code;
+
+/* XXX need to deal with DECLINED vs DENIED. DECLINED may not even
+ be needed since we are only going to call registered require providers.
+ I assume that it will deal with passing from one provider to the next
+ according to the order and the Authz_xxx_Authoritative directives.
+*/
+ switch (auth_result) {
+ case AUTH_DENIED:
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+ "user %s: authorization failure for \"%s\": ",
+ r->user, r->uri);
+ return_code = HTTP_UNAUTHORIZED;
+ break;
+ case AUTH_GENERAL_ERROR:
+ default:
+ /* We'll assume that the module has already said what its error
+ * was in the logs.
+ */
+ return_code = HTTP_INTERNAL_SERVER_ERROR;
+ break;
+ }
+
+ /* If we're returning 403, tell them to try again. */
+ if (return_code == HTTP_UNAUTHORIZED) {
+ ap_note_basic_auth_failure (r);
+ }
+ return return_code;
+ }
+
+ return OK;
+}
+
+static const apr_array_header_t *authz_host_ap_requires(request_rec *r)
+{
+ authz_host_dir_conf *conf;
+
+ conf = (authz_host_dir_conf *)ap_get_module_config(r->per_dir_config,
+ &authz_host_module);
+
+ return conf->ap_requires;
+}
+
+/*
+static const char *authz_host_ap_auth_type(request_rec *r)
+{
+ authz_host_dir_conf *conf;
+
+ conf = (authz_host_dir_conf *)ap_get_module_config(r->per_dir_config,
+ &authz_host_module);
+
+ return conf->ap_auth_type;
+}
+
+static const char *authz_host_ap_auth_name(request_rec *r)
+{
+ authz_host_dir_conf *conf;
+
+ conf = (authz_host_dir_conf *)ap_get_module_config(r->per_dir_config,
+ &authz_host_module);
+
+ return conf->ap_auth_name;
+}
+*/
+
static void register_hooks(apr_pool_t *p)
{
+ APR_REGISTER_OPTIONAL_FN(authz_host_ap_requires);
+ /*
+ APR_REGISTER_OPTIONAL_FN(authz_host_ap_auth_type);
+ APR_REGISTER_OPTIONAL_FN(authz_host_ap_auth_name);
+ */
+
/* 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);
+ ap_hook_auth_checker(authorize_user, 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 */
+ merge_authz_host_dir_config, /* dir merger --- default is to override */
NULL, /* server config */
NULL, /* merge server config */
authz_host_cmds,
Modified: httpd/httpd/branches/authz-dev/server/core.c
URL: http://svn.apache.org/viewcvs/httpd/httpd/branches/authz-dev/server/core.c?rev=349875&r1=349874&r2=349875&view=diff
==============================================================================
--- httpd/httpd/branches/authz-dev/server/core.c (original)
+++ httpd/httpd/branches/authz-dev/server/core.c Tue Nov 29 20:22:48 2005
@@ -268,18 +268,6 @@
conf->ap_default_type = new->ap_default_type;
}
- if (new->ap_auth_type) {
- conf->ap_auth_type = new->ap_auth_type;
- }
-
- if (new->ap_auth_name) {
- conf->ap_auth_name = new->ap_auth_name;
- }
-
- if (new->ap_requires) {
- conf->ap_requires = new->ap_requires;
- }
-
if (conf->response_code_strings == NULL) {
conf->response_code_strings = new->response_code_strings;
}
@@ -675,21 +663,51 @@
core_dir_config *conf;
conf = (core_dir_config *)ap_get_module_config(r->per_dir_config,
- &core_module);
+ &core_module);
return conf->ap_auth_type;
}
+/*
+ * Optional function coming from mod_ident, used for looking up ident user
+ */
+/*
+static APR_OPTIONAL_FN_TYPE(authz_host_ap_auth_type) *azh_ap_auth_type;
+
+AP_DECLARE(const char *) ap_auth_type(request_rec *r)
+{
+ if (azh_ap_auth_type) {
+ return azh_ap_auth_type(r);
+ }
+ return NULL;
+}
+*/
+
AP_DECLARE(const char *) ap_auth_name(request_rec *r)
{
core_dir_config *conf;
conf = (core_dir_config *)ap_get_module_config(r->per_dir_config,
- &core_module);
+ &core_module);
return conf->ap_auth_name;
}
+/*
+ * Optional function coming from mod_ident, used for looking up ident user
+ */
+/*
+static APR_OPTIONAL_FN_TYPE(authz_host_ap_auth_name) *azh_ap_auth_name;
+
+AP_DECLARE(const char *) ap_auth_name(request_rec *r)
+{
+ if (azh_ap_auth_name) {
+ return azh_ap_auth_name(r);
+ }
+ return NULL;
+}
+*/
+
AP_DECLARE(const char *) ap_default_type(request_rec *r)
{
core_dir_config *conf;
@@ -712,14 +730,17 @@
return conf->ap_document_root;
}
+/*
+ * Optional function coming from mod_ident, used for looking up ident user
+ */
+static APR_OPTIONAL_FN_TYPE(authz_host_ap_requires) *azh_ap_requires;
+
AP_DECLARE(const apr_array_header_t *) ap_requires(request_rec *r)
{
- core_dir_config *conf;
-
- conf = (core_dir_config *)ap_get_module_config(r->per_dir_config,
- &core_module);
-
- return conf->ap_requires;
+ if (azh_ap_requires) {
+ return azh_ap_requires(r);
+ }
+ return NULL;
}
AP_DECLARE(int) ap_satisfies(request_rec *r)
@@ -1684,22 +1705,6 @@
return NULL;
}
-static const char *require(cmd_parms *cmd, void *c_, const char *arg)
-{
- require_line *r;
- core_dir_config *c = c_;
-
- if (!c->ap_requires) {
- c->ap_requires = apr_array_make(cmd->pool, 2, sizeof(require_line));
- }
-
- r = (require_line *)apr_array_push(c->ap_requires);
- r->requirement = apr_pstrdup(cmd->pool, arg);
- r->method_mask = cmd->limited;
-
- return NULL;
-}
-
/*
* Report a missing-'>' syntax error.
*/
@@ -3232,8 +3237,6 @@
"An HTTP authorization type (e.g., \"Basic\")"),
AP_INIT_TAKE1("AuthName", set_authname, NULL, OR_AUTHCFG,
"The authentication realm (e.g. \"Members Only\")"),
-AP_INIT_RAW_ARGS("Require", require, NULL, OR_AUTHCFG,
- "Selects which authenticated users or groups may access a protected space"),
AP_INIT_TAKE1("Satisfy", satisfy, NULL, OR_AUTHCFG,
"access policy if both allow and require used ('all' or 'any')"),
#ifdef GPROF
@@ -3723,6 +3726,11 @@
{
logio_add_bytes_out = APR_RETRIEVE_OPTIONAL_FN(ap_logio_add_bytes_out);
ident_lookup = APR_RETRIEVE_OPTIONAL_FN(ap_ident_lookup);
+ azh_ap_requires = APR_RETRIEVE_OPTIONAL_FN(authz_host_ap_requires);
+ /*
+ azh_ap_auth_type = APR_RETRIEVE_OPTIONAL_FN(authz_host_ap_auth_type);
+ azh_ap_auth_name = APR_RETRIEVE_OPTIONAL_FN(authz_host_ap_auth_name);
+ */
ap_set_version(pconf);
ap_setup_make_content_type(pconf);