diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-08-05 16:22:51 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-08-05 16:22:51 +0000 |
commit | cf46733632c7279a9fd0fe6ce26f9185a4ae82a9 (patch) | |
tree | da27775a2161723ef342e91af41a8b51fedef405 /subversion/libsvn_repos/authz_pool.c | |
parent | bb0ef45f7c46b0ae221b26265ef98a768c33f820 (diff) | |
download | subversion-tarball-master.tar.gz |
subversion-1.9.7HEADsubversion-1.9.7master
Diffstat (limited to 'subversion/libsvn_repos/authz_pool.c')
-rw-r--r-- | subversion/libsvn_repos/authz_pool.c | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/subversion/libsvn_repos/authz_pool.c b/subversion/libsvn_repos/authz_pool.c new file mode 100644 index 0000000..f8ac528 --- /dev/null +++ b/subversion/libsvn_repos/authz_pool.c @@ -0,0 +1,226 @@ +/* + * authz_pool.c : pool of authorization objects + * + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + */ + + + +#include "svn_checksum.h" +#include "svn_config.h" +#include "svn_error.h" +#include "svn_pools.h" + +#include "private/svn_dep_compat.h" +#include "private/svn_mutex.h" +#include "private/svn_object_pool.h" +#include "private/svn_subr_private.h" +#include "private/svn_repos_private.h" +#include "private/svn_string_private.h" +#include "private/svn_subr_private.h" + +#include "repos.h" + +/* Currently this structure is just a wrapper around a svn_config_t. + */ +struct svn_authz_t +{ + svn_config_t *cfg; +}; + +/* The wrapper object structure that we store in the object pool. It + * combines the authz with the underlying config structures and their + * identifying keys. + */ +typedef struct authz_object_t +{ + /* key = concatenation of AUTHZ_KEY and GROUPS_KEY */ + svn_membuf_t *key; + + /* keys used to identify AUTHZ_CFG and GROUPS_CFG */ + svn_membuf_t *authz_key; + svn_membuf_t *groups_key; + + /* r/o references to configurations from the configuration pool. + GROUPS_CFG may be NULL. */ + svn_config_t *authz_cfg; + svn_config_t *groups_cfg; + + /* Case-sensitive config. */ + svn_authz_t *authz; +} authz_object_t; + +/* Root data structure simply adding the config_pool to the basic object pool. + */ +struct svn_repos__authz_pool_t +{ + /* authz_object_t object storage */ + svn_object_pool__t *object_pool; + + /* factory and storage of (shared) configuration objects */ + svn_repos__config_pool_t *config_pool; +}; + +/* Return a combination of AUTHZ_KEY and GROUPS_KEY, allocated in POOL. + * GROUPS_KEY may be NULL. + */ +static svn_membuf_t * +construct_key(svn_membuf_t *authz_key, + svn_membuf_t *groups_key, + apr_pool_t *pool) +{ + svn_membuf_t *result = apr_pcalloc(pool, sizeof(*result)); + apr_size_t size; + if (groups_key) + { + size = authz_key->size + groups_key->size; + svn_membuf__create(result,size, pool); + memcpy(result->data, authz_key->data, authz_key->size); + memcpy((char *)result->data + authz_key->size, + groups_key->data, groups_key->size); + } + else + { + size = authz_key->size; + svn_membuf__create(result, size, pool); + memcpy(result->data, authz_key->data, authz_key->size); + } + + result->size = size; + return result; +} + +/* Implement svn_object_pool__getter_t on authz_object_t structures. + */ +static void * +getter(void *object, + void *baton, + apr_pool_t *pool) +{ + return ((authz_object_t *)object)->authz; +} + +/* API implementation */ + +svn_error_t * +svn_repos__authz_pool_create(svn_repos__authz_pool_t **authz_pool, + svn_repos__config_pool_t *config_pool, + svn_boolean_t thread_safe, + apr_pool_t *pool) +{ + svn_repos__authz_pool_t *result; + svn_object_pool__t *object_pool; + + /* there is no setter as we don't need to update existing authz */ + SVN_ERR(svn_object_pool__create(&object_pool, getter, NULL, thread_safe, + pool)); + + result = apr_pcalloc(pool, sizeof(*result)); + result->object_pool = object_pool; + result->config_pool = config_pool; + + *authz_pool = result; + return SVN_NO_ERROR; +} + +svn_error_t * +svn_repos__authz_pool_get(svn_authz_t **authz_p, + svn_repos__authz_pool_t *authz_pool, + const char *path, + const char *groups_path, + svn_boolean_t must_exist, + svn_repos_t *preferred_repos, + apr_pool_t *pool) +{ + apr_pool_t *authz_ref_pool + = svn_object_pool__new_wrapper_pool(authz_pool->object_pool); + authz_object_t *authz_ref + = apr_pcalloc(authz_ref_pool, sizeof(*authz_ref)); + svn_boolean_t have_all_keys; + + /* read the configurations */ + SVN_ERR(svn_repos__config_pool_get(&authz_ref->authz_cfg, + &authz_ref->authz_key, + authz_pool->config_pool, + path, must_exist, TRUE, + preferred_repos, authz_ref_pool)); + have_all_keys = authz_ref->authz_key != NULL; + + if (groups_path) + { + SVN_ERR(svn_repos__config_pool_get(&authz_ref->groups_cfg, + &authz_ref->groups_key, + authz_pool->config_pool, + groups_path, must_exist, TRUE, + preferred_repos, authz_ref_pool)); + have_all_keys &= authz_ref->groups_key != NULL; + } + + /* fall back to standard implementation in case we don't have all the + * facts (i.e. keys). */ + if (!have_all_keys) + return svn_error_trace(svn_repos_authz_read2(authz_p, path, groups_path, + must_exist, pool)); + + /* all keys are known and lookup is unambigious. */ + authz_ref->key = construct_key(authz_ref->authz_key, + authz_ref->groups_key, + authz_ref_pool); + + SVN_ERR(svn_object_pool__lookup((void **)authz_p, authz_pool->object_pool, + authz_ref->key, NULL, pool)); + if (*authz_p) + { + svn_pool_destroy(authz_ref_pool); + return SVN_NO_ERROR; + } + + authz_ref->authz = apr_palloc(authz_ref_pool, sizeof(*authz_ref->authz)); + authz_ref->authz->cfg = authz_ref->authz_cfg; + + if (groups_path) + { + /* Easy out: we prohibit local groups in the authz file when global + groups are being used. */ + if (svn_config_has_section(authz_ref->authz->cfg, + SVN_CONFIG_SECTION_GROUPS)) + return svn_error_createf(SVN_ERR_AUTHZ_INVALID_CONFIG, NULL, + "Error reading authz file '%s' with " + "groups file '%s':" + "Authz file cannot contain any groups " + "when global groups are being used.", + path, groups_path); + + /* We simply need to add the [Groups] section to the authz config. + */ + svn_config__shallow_replace_section(authz_ref->authz->cfg, + authz_ref->groups_cfg, + SVN_CONFIG_SECTION_GROUPS); + } + + /* Make sure there are no errors in the configuration. */ + SVN_ERR(svn_repos__authz_validate(authz_ref->authz, authz_ref_pool)); + + SVN_ERR(svn_object_pool__insert((void **)authz_p, authz_pool->object_pool, + authz_ref->key, authz_ref, NULL, + authz_ref_pool, pool)); + + return SVN_NO_ERROR; +} |