summaryrefslogtreecommitdiffstats
path: root/modules/aaa/mod_authz_owner.c
diff options
context:
space:
mode:
authorAndré Malo <nd@apache.org>2003-01-15 23:08:54 +0100
committerAndré Malo <nd@apache.org>2003-01-15 23:08:54 +0100
commitca0c66ee6f918420ae3a65546dcb42298bce1111 (patch)
tree04fbd7240e121a0c029c6fec995a6cd35ef4a77c /modules/aaa/mod_authz_owner.c
parent It's up to apr-iconv to install it's own ces/ccs .pdb symbols. (diff)
downloadapache2-ca0c66ee6f918420ae3a65546dcb42298bce1111.tar.xz
apache2-ca0c66ee6f918420ae3a65546dcb42298bce1111.zip
as announced and with no objections:
mod_authz_owner: forward port of require file-owner/file-group functionality The goal of the module is to do all the neccessary file system work to figure out username and groupname. "Require file-owner" is completely resolved within the module. "file-group" is only determined there and the groupname will be extracted from the stat call and stored within the r->notes. Done that, the module will decline, so that the group database modules (mod_authz_groupfile, mod_authz_dbm) can verify the groupname with their lists. Thus every group module that supports the file-group requirement must be hooked after mod_authz_owner. They have to recognize "file-group" and read the groupname from r->notes. (If there's no name stored, the modules should ignore the file-group requirement). The backstopper module will do its work in worst case. not solved yet: - the module doesn't work as one could expect if the file doesn't exist in the first request round (consider MultiViews) (the 1.3 version has the same problem). I played around with some subrequest techniques, but got no helpful result. Is there any magic to recognize the actual resulting filename (if there is)? git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@98281 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'modules/aaa/mod_authz_owner.c')
-rw-r--r--modules/aaa/mod_authz_owner.c295
1 files changed, 295 insertions, 0 deletions
diff --git a/modules/aaa/mod_authz_owner.c b/modules/aaa/mod_authz_owner.c
new file mode 100644
index 0000000000..f679b9aff5
--- /dev/null
+++ b/modules/aaa/mod_authz_owner.c
@@ -0,0 +1,295 @@
+/* ====================================================================
+ * 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_file_info.h"
+#include "apr_user.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"
+
+#include "mod_auth.h" /* for AUTHZ_GROUP_NOTE */
+
+typedef struct {
+ int authoritative;
+} authz_owner_config_rec;
+
+static void *create_authz_owner_dir_config(apr_pool_t *p, char *d)
+{
+ authz_owner_config_rec *conf = apr_palloc(p, sizeof(*conf));
+
+ conf->authoritative = 1; /* keep the fortress secure by default */
+ return conf;
+}
+
+static const command_rec authz_owner_cmds[] =
+{
+ AP_INIT_FLAG("AuthzOwnerAuthoritative", ap_set_flag_slot,
+ (void *)APR_OFFSETOF(authz_owner_config_rec, authoritative),
+ OR_AUTHCFG,
+ "Set to 'Off' to allow access control to be passed along to "
+ "lower modules. (default is On.)"),
+ {NULL}
+};
+
+module AP_MODULE_DECLARE_DATA authz_owner_module;
+
+static int check_file_owner(request_rec *r)
+{
+ authz_owner_config_rec *conf = ap_get_module_config(r->per_dir_config,
+ &authz_owner_module);
+ int m = r->method_number;
+ register int x;
+ const char *t, *w;
+ const apr_array_header_t *reqs_arr = ap_requires(r);
+ require_line *reqs;
+ int required_owner = 0;
+ apr_status_t status = 0;
+ char *reason = NULL;
+
+ if (!reqs_arr) {
+ return DECLINED;
+ }
+
+ reqs = (require_line *)reqs_arr->elts;
+ for (x = 0; x < reqs_arr->nelts; x++) {
+
+ /* if authoritative = On then break if a require already failed. */
+ if (reason && conf->authoritative) {
+ break;
+ }
+
+ if (!(reqs[x].method_mask & (AP_METHOD_BIT << m))) {
+ continue;
+ }
+
+ t = reqs[x].requirement;
+ w = ap_getword_white(r->pool, &t);
+
+ if (!strcmp(w, "file-owner")) {
+#if !APR_HAS_USER
+ if ((required_owner & ~1) && conf->authoritative) {
+ break;
+ }
+
+ required_owner |= 1; /* remember the requirement */
+ reason = "'Require file-owner' is not supported on this platform.";
+ continue;
+#else /* APR_HAS_USER */
+ char *owner = NULL;
+ apr_finfo_t finfo;
+
+ if ((required_owner & ~1) && conf->authoritative) {
+ break;
+ }
+
+ required_owner |= 1; /* remember the requirement */
+
+ if (!r->filename) {
+ reason = "no filename available";
+ continue;
+ }
+
+ status = apr_stat(&finfo, r->filename, APR_FINFO_USER, r->pool);
+ if (status != APR_SUCCESS) {
+ reason = apr_pstrcat(r->pool, "could not stat file ",
+ r->filename, NULL);
+ continue;
+ }
+
+ if (!(finfo.valid & APR_FINFO_USER)) {
+ reason = "no file owner information available";
+ continue;
+ }
+
+ status = apr_uid_name_get(&owner, finfo.user, r->pool);
+ if (status != APR_SUCCESS || !owner) {
+ reason = "could not get name of file owner";
+ continue;
+ }
+
+ if (strcmp(owner, r->user)) {
+ reason = apr_psprintf(r->pool, "file owner %s does not match.",
+ owner);
+ continue;
+ }
+
+ /* this user is authorized */
+ return OK;
+#endif /* APR_HAS_USER */
+ }
+
+ /* file-group only figures out the file's group and lets
+ * other modules do the actual authorization (against a group file/db).
+ * Thus, these modules have to hook themselves after
+ * mod_authz_owner and of course recognize 'file-group', too.
+ */
+ if (!strcmp(w, "file-group")) {
+#if !APR_HAS_USER
+ if ((required_owner & ~6) && conf->authoritative) {
+ break;
+ }
+
+ required_owner |= 2; /* remember the requirement */
+ reason = "'Require file-group' is not supported on this platform.";
+ continue;
+#else /* APR_HAS_USER */
+ char *group = NULL;
+ apr_finfo_t finfo;
+
+ if ((required_owner & ~6) && conf->authoritative) {
+ break;
+ }
+
+ required_owner |= 2; /* remember the requirement */
+
+ if (!r->filename) {
+ reason = "no filename available";
+ continue;
+ }
+
+ status = apr_stat(&finfo, r->filename, APR_FINFO_GROUP, r->pool);
+ if (status != APR_SUCCESS) {
+ reason = apr_pstrcat(r->pool, "could not stat file ",
+ r->filename, NULL);
+ continue;
+ }
+
+ if (!(finfo.valid & APR_FINFO_GROUP)) {
+ reason = "no file group information available";
+ continue;
+ }
+
+ status = apr_gid_name_get(&group, finfo.group, r->pool);
+ if (status != APR_SUCCESS || !group) {
+ reason = "could not get name of file group";
+ continue;
+ }
+
+ /* store group name in a note and let others decide... */
+ apr_table_setn(r->notes, AUTHZ_GROUP_NOTE, group);
+ required_owner |= 4;
+ continue;
+#endif /* APR_HAS_USER */
+ }
+ }
+
+ if (!required_owner || !conf->authoritative) {
+ return DECLINED;
+ }
+
+ /* allow file-group passed to group db modules either if this is the
+ * only applicable requirement here or if a file-owner failed but we're
+ * not authoritative.
+ * This allows configurations like:
+ *
+ * AuthzOwnerAuthoritative Off
+ * require file-owner
+ * require file-group
+ *
+ * with the semantical meaning of "either owner or group must match"
+ * (inclusive or)
+ *
+ * [ 6 == 2 | 4; 7 == 1 | 2 | 4 ] should I use #defines instead?
+ */
+ if (required_owner == 6 || (required_owner == 7 && !conf->authoritative)) {
+ return DECLINED;
+ }
+
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r,
+ "Authorization of user %s to access %s failed, reason: %s",
+ r->user, r->uri, reason ? reason : "unknown");
+
+ ap_note_auth_failure(r);
+ return HTTP_UNAUTHORIZED;
+}
+
+static void register_hooks(apr_pool_t *p)
+{
+ ap_hook_auth_checker(check_file_owner, NULL, NULL, APR_HOOK_MIDDLE);
+}
+
+module AP_MODULE_DECLARE_DATA authz_owner_module =
+{
+ STANDARD20_MODULE_STUFF,
+ create_authz_owner_dir_config, /* dir config creater */
+ NULL, /* dir merger --- default is to override */
+ NULL, /* server config */
+ NULL, /* merge server config */
+ authz_owner_cmds, /* command apr_table_t */
+ register_hooks /* register hooks */
+};