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

📄 mod_authz_svn.c

📁 linux subdivision ying gai ke yi le ba
💻 C
📖 第 1 页 / 共 2 页
字号:
    svn_error_t *svn_err;
    const char *cache_key;
    void *user_data;

    switch (r->method_number) {
    /* All methods requiring read access to all subtrees of r->uri */
    case M_COPY:
        authz_svn_type |= AUTHZ_SVN_RECURSIVE;

    /* All methods requiring read access to r->uri */
    case M_OPTIONS:
    case M_GET:
    case M_PROPFIND:
    case M_REPORT:
        authz_svn_type |= AUTHZ_SVN_READ;
        break;

    /* All methods requiring write access to all subtrees of r->uri */
    case M_MOVE:
    case M_DELETE:
        authz_svn_type |= AUTHZ_SVN_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:
        authz_svn_type |= AUTHZ_SVN_WRITE;
        break;

    default:
        /* Require most strict access for unknown methods */
        authz_svn_type |= AUTHZ_SVN_WRITE|AUTHZ_SVN_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);

        dest_uri = parsed_dest_uri.path;
        ap_unescape_url((char *)dest_uri);
        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_config_read(&access_conf, conf->access_file, FALSE,
                                  r->connection->pool);
        if (svn_err) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, svn_err->apr_err, r,
                          "%s", svn_err->message);

            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);
    }

    if (!check_access(access_conf,
                      repos_name, repos_path,
                      r->user, authz_svn_type,
                      r->pool)) {
        return DECLINED;
    }

    /* XXX: MKCOL, MOVE, DELETE
     * XXX: Require write access to the parent dir of repos_path.
     */

    /* XXX: PUT
     * XXX: If the path doesn't exist, require write access to the
     * XXX: parent dir of repos_path.
     */

    /* Only MOVE and COPY have a second uri we have to check access to. */
    if (r->method_number != M_MOVE
        && r->method_number != M_COPY) {
        return OK;
    }

    /* Check access on the first repos_path */
    if (!check_access(access_conf,
                      dest_repos_name, dest_repos_path,
                      r->user, AUTHZ_SVN_WRITE|AUTHZ_SVN_RECURSIVE,
                      r->pool)) {
        return DECLINED;
    }

    /* XXX: MOVE and COPY, if the path doesn't exist yet, also
     * XXX: require write access to the parent dir of dest_repos_path.
     */

    return OK;
}

/*
 * Hooks
 */

static int access_checker(request_rec *r)
{
    authz_svn_config_rec *conf = ap_get_module_config(r->per_dir_config,
                                                      &authz_svn_module);
    const char *repos_path;
    const char *dest_repos_path = NULL;
    int status;

    /* We are not configured to run */
    if (!conf->anonymous || !conf->access_file)
        return DECLINED;

    if (ap_some_auth_required(r)) {
        /* It makes no sense to check if a location is both accessible
         * anonymous and by an authenticated user (in the same request!).
         */
        if (ap_satisfies(r) != SATISFY_ANY)
            return DECLINED;

        /* If the user is trying to authenticate, let him.  If anonymous
         * access is allowed, so is authenticated access, by definition
         * of the meaning of '*' in the access file.
         */
        if (apr_table_get(r->headers_in,
                          (PROXYREQ_PROXY == r->proxyreq)
                          ? "Proxy-Authorization" : "Authorization")) {
            /* Given Satisfy Any is in effect, we have to forbid access
             * to let the auth_checker hook have a go at it.
             */
            return HTTP_FORBIDDEN;
        }
    }

    /* If anon access is allowed, return OK */
    status = req_check_access(r, conf, &repos_path, &dest_repos_path);
    if (status == DECLINED) {
        if (!conf->authoritative)
            return DECLINED;

        if (!ap_some_auth_required(r)) {
            if (dest_repos_path) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                    "Access denied: - %s %s %s",
                    r->method, repos_path, dest_repos_path);
            }
            else {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                    "Access denied: - %s %s",
                    r->method, repos_path);
            }

        }

        return HTTP_FORBIDDEN;
    }

    if (status != OK)
        return status;

    if (dest_repos_path) {
        ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
            "Access granted: - %s %s %s",
            r->method, repos_path, dest_repos_path);
    }
    else {
        ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
            "Access granted: - %s %s",
            r->method, repos_path);
    }

    return OK;
}

static int auth_checker(request_rec *r)
{
    authz_svn_config_rec *conf = ap_get_module_config(r->per_dir_config,
                                                      &authz_svn_module);
    const char *repos_path;
    const char *dest_repos_path = NULL;
    int status;

    /* We are not configured to run */
    if (!conf->access_file)
        return DECLINED;

    status = req_check_access(r, conf, &repos_path, &dest_repos_path);
    if (status == DECLINED) {
        if (conf->authoritative) {
            if (dest_repos_path) {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                    "Access denied: '%s' %s %s %s",
                    r->user, r->method, repos_path, dest_repos_path);
            }
            else {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
                    "Access denied: '%s' %s %s",
                    r->user, r->method, repos_path);
            }
            ap_note_auth_failure(r);
            return HTTP_UNAUTHORIZED;
        }

        return DECLINED;
    }

    if (status != OK)
        return status;

    if (dest_repos_path) {
        ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
            "Access granted: '%s' %s %s %s",
            r->user, r->method, repos_path, dest_repos_path);
    }
    else {
        ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
            "Access granted: '%s' %s %s",
            r->user, r->method, repos_path);
    }

    return OK;
}

/*
 * Module flesh
 */

static void register_hooks(apr_pool_t *p)
{
    ap_hook_access_checker(access_checker, NULL, NULL, APR_HOOK_LAST);
    ap_hook_auth_checker(auth_checker, NULL, NULL, APR_HOOK_FIRST);
}

module AP_MODULE_DECLARE_DATA authz_svn_module =
{
    STANDARD20_MODULE_STUFF,
    create_authz_svn_dir_config,     /* dir config creater */
    NULL,                            /* dir merger --- default is to override */
    NULL,                            /* server config */
    NULL,                            /* merge server config */
    authz_svn_cmds,                  /* command apr_table_t */
    register_hooks                   /* register hooks */
};

⌨️ 快捷键说明

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