⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mod_authz_svn.c

📁 subversion-1.4.3-1.tar.gz 配置svn的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * mod_authz_svn.c: an Apache mod_dav_svn sub-module to provide path *                  based authorization for a Subversion repository. * * ==================================================================== * Copyright (c) 2003-2005 CollabNet.  All rights reserved. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution.  The terms * are also available at http://subversion.tigris.org/license-1.html. * If newer versions of this license are posted there, you may use a * newer version instead, at your option. * * This software consists of voluntary contributions made by many * individuals.  For exact contribution history, see the revision * history and logs, available at http://subversion.tigris.org/. * ==================================================================== */#include <httpd.h>#include <http_config.h>#include <http_core.h>#include <http_request.h>#include <http_protocol.h>#include <http_log.h>#include <ap_config.h>#include <apr_uri.h>#include <mod_dav.h>#if AP_MODULE_MAGIC_AT_LEAST(20060110,0)#include <mod_auth.h>extern APR_OPTIONAL_FN_TYPE(ap_satisfies) *ap_satisfies;#endif#include "mod_dav_svn.h"#include "svn_path.h"#include "svn_config.h"#include "svn_string.h"#include "svn_repos.h"extern module AP_MODULE_DECLARE_DATA authz_svn_module;typedef struct {    int authoritative;    int anonymous;    int no_auth_when_anon_ok;    const char *base_path;    const char *access_file;} authz_svn_config_rec;/* * Configuration */static void *create_authz_svn_dir_config(apr_pool_t *p, char *d){    authz_svn_config_rec *conf = apr_pcalloc(p, sizeof(*conf));    conf->base_path = d;    /* By default keep the fortress secure */    conf->authoritative = 1;    conf->anonymous = 1;    return conf;}static const command_rec authz_svn_cmds[] ={    AP_INIT_FLAG("AuthzSVNAuthoritative", ap_set_flag_slot,                 (void *)APR_OFFSETOF(authz_svn_config_rec, authoritative),                 OR_AUTHCFG,                 "Set to 'Off' to allow access control to be passed along to "                 "lower modules. (default is On.)"),    AP_INIT_TAKE1("AuthzSVNAccessFile", ap_set_file_slot,                  (void *)APR_OFFSETOF(authz_svn_config_rec, access_file),                  OR_AUTHCFG,                  "Text file containing permissions of repository paths."),    AP_INIT_FLAG("AuthzSVNAnonymous", ap_set_flag_slot,                 (void *)APR_OFFSETOF(authz_svn_config_rec, anonymous),                 OR_AUTHCFG,                 "Set to 'Off' to disable two special-case behaviours of "                 "this module: (1) interaction with the 'Satisfy Any' "                 "directive, and (2) enforcement of the authorization "                 "policy even when no 'Require' directives are present. "                 "(default is On.)"),    AP_INIT_FLAG("AuthzSVNNoAuthWhenAnonymousAllowed", ap_set_flag_slot,                 (void *)APR_OFFSETOF(authz_svn_config_rec,                                      no_auth_when_anon_ok),                 OR_AUTHCFG,                 "Set to 'On' to suppress authentication and authorization "                 "for requests which anonymous users are allowed to perform. "                 "(default is Off.)"),    { NULL }};/* Check if the current request R is allowed.  Upon exit *REPOS_PATH_REF * will contain the path and repository name that an operation was requested * on in the form 'name:path'.  *DEST_REPOS_PATH_REF will contain the * destination path if the requested operation was a MOVE or a COPY. * Returns OK when access is allowed, DECLINED when it isn't, or an HTTP_ * error code when an error occurred. */static int req_check_access(request_rec *r,                            authz_svn_config_rec *conf,                            const char **repos_path_ref,                            const char **dest_repos_path_ref){    const char *dest_uri;    apr_uri_t parsed_dest_uri;    const char *cleaned_uri;    int trailing_slash;    const char *repos_name;    const char *dest_repos_name;    const char *relative_path;    const char *repos_path;    const char *dest_repos_path = NULL;    dav_error *dav_err;    svn_repos_authz_access_t authz_svn_type = svn_authz_none;    svn_boolean_t authz_access_granted = FALSE;    svn_authz_t *access_conf = NULL;    svn_error_t *svn_err;    const char *cache_key;    void *user_data;    char errbuf[256];    switch (r->method_number) {    /* All methods requiring read access to all subtrees of r->uri */    case M_COPY:      authz_svn_type |= svn_authz_recursive;    /* All methods requiring read access to r->uri */    case M_OPTIONS:    case M_GET:    case M_PROPFIND:    case M_REPORT:      authz_svn_type |= svn_authz_read;      break;    /* All methods requiring write access to all subtrees of r->uri */    case M_MOVE:    case M_DELETE:      authz_svn_type |= svn_authz_recursive;    /* All methods requiring write access to r->uri */    case M_MKCOL:    case M_PUT:    case M_PROPPATCH:    case M_CHECKOUT:    case M_MERGE:    case M_MKACTIVITY:    case M_LOCK:    case M_UNLOCK:      authz_svn_type |= svn_authz_write;      break;    default:      /* Require most strict access for unknown methods */      authz_svn_type |= svn_authz_write | svn_authz_recursive;      break;    }    dav_err = dav_svn_split_uri(r,                                r->uri,                                conf->base_path,                                &cleaned_uri,                                &trailing_slash,                                &repos_name,                                &relative_path,                                &repos_path);    if (dav_err) {        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,                      "%s  [%d, #%d]",                      dav_err->desc, dav_err->status, dav_err->error_id);        /* Ensure that we never allow access by dav_err->status */        return (dav_err->status != OK && dav_err->status != DECLINED) ?            dav_err->status : HTTP_INTERNAL_SERVER_ERROR;    }    /* Ignore the URI passed to MERGE, like mod_dav_svn does.     * See issue #1821.     * XXX: When we start accepting a broader range of DeltaV MERGE     * XXX: requests, this should be revisited.     */    if (r->method_number == M_MERGE) {        repos_path = NULL;    }    if (repos_path)        repos_path = svn_path_join("/", repos_path, r->pool);    *repos_path_ref = apr_pstrcat(r->pool, repos_name, ":", repos_path, NULL);    if (r->method_number == M_MOVE || r->method_number == M_COPY) {        dest_uri = apr_table_get(r->headers_in, "Destination");        /* Decline MOVE or COPY when there is no Destination uri, this will         * cause failure.         */        if (!dest_uri)            return DECLINED;        apr_uri_parse(r->pool, dest_uri, &parsed_dest_uri);        ap_unescape_url(parsed_dest_uri.path);        dest_uri = parsed_dest_uri.path;        if (strncmp(dest_uri, conf->base_path, strlen(conf->base_path))) {            /* If it is not the same location, then we don't allow it.             * XXX: Instead we could compare repository uuids, but that             * XXX: seems a bit over the top.             */            return HTTP_BAD_REQUEST;        }        dav_err = dav_svn_split_uri(r,                                    dest_uri,                                    conf->base_path,                                    &cleaned_uri,                                    &trailing_slash,                                    &dest_repos_name,                                    &relative_path,                                    &dest_repos_path);        if (dav_err) {            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,                          "%s  [%d, #%d]",                          dav_err->desc, dav_err->status, dav_err->error_id);            /* Ensure that we never allow access by dav_err->status */            return (dav_err->status != OK && dav_err->status != DECLINED) ?                dav_err->status : HTTP_INTERNAL_SERVER_ERROR;        }        if (dest_repos_path)            dest_repos_path = svn_path_join("/", dest_repos_path, r->pool);        *dest_repos_path_ref = apr_pstrcat(r->pool, dest_repos_name, ":",                                           dest_repos_path, NULL);    }    /* Retrieve/cache authorization file */    cache_key = apr_pstrcat(r->pool, "mod_authz_svn:", conf->access_file, NULL);    apr_pool_userdata_get(&user_data, cache_key, r->connection->pool);    access_conf = user_data;    if (access_conf == NULL) {        svn_err = svn_repos_authz_read(&access_conf, conf->access_file,                                       TRUE, r->connection->pool);        if (svn_err) {            ap_log_rerror(APLOG_MARK, APLOG_ERR,                          /* If it is an error code that APR can make sense                             of, then show it, otherwise, pass zero to avoid                             putting "APR does not understand this error code"                             in the error log. */                          ((svn_err->apr_err >= APR_OS_START_USERERR &&                            svn_err->apr_err < APR_OS_START_CANONERR) ?                           0 : svn_err->apr_err),                          r, "Failed to load the AuthzSVNAccessFile: %s",                          svn_err_best_message(svn_err,                                               errbuf, sizeof(errbuf)));            svn_error_clear(svn_err);            return DECLINED;        }        /* Cache the open repos for the next request on this connection */        apr_pool_userdata_set(access_conf, cache_key,                              NULL, r->connection->pool);    }    /* Perform authz access control.     *     * First test the special case where repos_path == NULL, and skip     * calling the authz routines in that case.  This is an oddity of     * the DAV RA method: some requests have no repos_path, but apache     * still triggers an authz lookup for the URI.     *     * However, if repos_path == NULL and the request requires write     * access, then perform a global authz lookup.  The request is     * denied if the user commiting isn't granted any access anywhere

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -