authz_pool.c revision 299742
1/* 2 * authz_pool.c : pool of authorization objects 3 * 4 * ==================================================================== 5 * Licensed to the Apache Software Foundation (ASF) under one 6 * or more contributor license agreements. See the NOTICE file 7 * distributed with this work for additional information 8 * regarding copyright ownership. The ASF licenses this file 9 * to you under the Apache License, Version 2.0 (the 10 * "License"); you may not use this file except in compliance 11 * with the License. You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, 16 * software distributed under the License is distributed on an 17 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 18 * KIND, either express or implied. See the License for the 19 * specific language governing permissions and limitations 20 * under the License. 21 * ==================================================================== 22 */ 23 24 25 26#include "svn_checksum.h" 27#include "svn_config.h" 28#include "svn_error.h" 29#include "svn_pools.h" 30 31#include "private/svn_dep_compat.h" 32#include "private/svn_mutex.h" 33#include "private/svn_object_pool.h" 34#include "private/svn_subr_private.h" 35#include "private/svn_repos_private.h" 36#include "private/svn_string_private.h" 37#include "private/svn_subr_private.h" 38 39#include "repos.h" 40 41/* Currently this structure is just a wrapper around a svn_config_t. 42 */ 43struct svn_authz_t 44{ 45 svn_config_t *cfg; 46}; 47 48/* The wrapper object structure that we store in the object pool. It 49 * combines the authz with the underlying config structures and their 50 * identifying keys. 51 */ 52typedef struct authz_object_t 53{ 54 /* key = concatenation of AUTHZ_KEY and GROUPS_KEY */ 55 svn_membuf_t *key; 56 57 /* keys used to identify AUTHZ_CFG and GROUPS_CFG */ 58 svn_membuf_t *authz_key; 59 svn_membuf_t *groups_key; 60 61 /* r/o references to configurations from the configuration pool. 62 GROUPS_CFG may be NULL. */ 63 svn_config_t *authz_cfg; 64 svn_config_t *groups_cfg; 65 66 /* Case-sensitive config. */ 67 svn_authz_t *authz; 68} authz_object_t; 69 70/* Root data structure simply adding the config_pool to the basic object pool. 71 */ 72struct svn_repos__authz_pool_t 73{ 74 /* authz_object_t object storage */ 75 svn_object_pool__t *object_pool; 76 77 /* factory and storage of (shared) configuration objects */ 78 svn_repos__config_pool_t *config_pool; 79}; 80 81/* Return a combination of AUTHZ_KEY and GROUPS_KEY, allocated in POOL. 82 * GROUPS_KEY may be NULL. 83 */ 84static svn_membuf_t * 85construct_key(svn_membuf_t *authz_key, 86 svn_membuf_t *groups_key, 87 apr_pool_t *pool) 88{ 89 svn_membuf_t *result = apr_pcalloc(pool, sizeof(*result)); 90 apr_size_t size; 91 if (groups_key) 92 { 93 size = authz_key->size + groups_key->size; 94 svn_membuf__create(result,size, pool); 95 memcpy(result->data, authz_key->data, authz_key->size); 96 memcpy((char *)result->data + authz_key->size, 97 groups_key->data, groups_key->size); 98 } 99 else 100 { 101 size = authz_key->size; 102 svn_membuf__create(result, size, pool); 103 memcpy(result->data, authz_key->data, authz_key->size); 104 } 105 106 result->size = size; 107 return result; 108} 109 110/* Implement svn_object_pool__getter_t on authz_object_t structures. 111 */ 112static void * 113getter(void *object, 114 void *baton, 115 apr_pool_t *pool) 116{ 117 return ((authz_object_t *)object)->authz; 118} 119 120/* API implementation */ 121 122svn_error_t * 123svn_repos__authz_pool_create(svn_repos__authz_pool_t **authz_pool, 124 svn_repos__config_pool_t *config_pool, 125 svn_boolean_t thread_safe, 126 apr_pool_t *pool) 127{ 128 svn_repos__authz_pool_t *result; 129 svn_object_pool__t *object_pool; 130 131 /* there is no setter as we don't need to update existing authz */ 132 SVN_ERR(svn_object_pool__create(&object_pool, getter, NULL, thread_safe, 133 pool)); 134 135 result = apr_pcalloc(pool, sizeof(*result)); 136 result->object_pool = object_pool; 137 result->config_pool = config_pool; 138 139 *authz_pool = result; 140 return SVN_NO_ERROR; 141} 142 143svn_error_t * 144svn_repos__authz_pool_get(svn_authz_t **authz_p, 145 svn_repos__authz_pool_t *authz_pool, 146 const char *path, 147 const char *groups_path, 148 svn_boolean_t must_exist, 149 svn_repos_t *preferred_repos, 150 apr_pool_t *pool) 151{ 152 apr_pool_t *authz_ref_pool 153 = svn_object_pool__new_wrapper_pool(authz_pool->object_pool); 154 authz_object_t *authz_ref 155 = apr_pcalloc(authz_ref_pool, sizeof(*authz_ref)); 156 svn_boolean_t have_all_keys; 157 158 /* read the configurations */ 159 SVN_ERR(svn_repos__config_pool_get(&authz_ref->authz_cfg, 160 &authz_ref->authz_key, 161 authz_pool->config_pool, 162 path, must_exist, TRUE, 163 preferred_repos, authz_ref_pool)); 164 have_all_keys = authz_ref->authz_key != NULL; 165 166 if (groups_path) 167 { 168 SVN_ERR(svn_repos__config_pool_get(&authz_ref->groups_cfg, 169 &authz_ref->groups_key, 170 authz_pool->config_pool, 171 groups_path, must_exist, TRUE, 172 preferred_repos, authz_ref_pool)); 173 have_all_keys &= authz_ref->groups_key != NULL; 174 } 175 176 /* fall back to standard implementation in case we don't have all the 177 * facts (i.e. keys). */ 178 if (!have_all_keys) 179 return svn_error_trace(svn_repos_authz_read2(authz_p, path, groups_path, 180 must_exist, pool)); 181 182 /* all keys are known and lookup is unambigious. */ 183 authz_ref->key = construct_key(authz_ref->authz_key, 184 authz_ref->groups_key, 185 authz_ref_pool); 186 187 SVN_ERR(svn_object_pool__lookup((void **)authz_p, authz_pool->object_pool, 188 authz_ref->key, NULL, pool)); 189 if (*authz_p) 190 { 191 svn_pool_destroy(authz_ref_pool); 192 return SVN_NO_ERROR; 193 } 194 195 authz_ref->authz = apr_palloc(authz_ref_pool, sizeof(*authz_ref->authz)); 196 authz_ref->authz->cfg = authz_ref->authz_cfg; 197 198 if (groups_path) 199 { 200 /* Easy out: we prohibit local groups in the authz file when global 201 groups are being used. */ 202 if (svn_config_has_section(authz_ref->authz->cfg, 203 SVN_CONFIG_SECTION_GROUPS)) 204 return svn_error_createf(SVN_ERR_AUTHZ_INVALID_CONFIG, NULL, 205 "Error reading authz file '%s' with " 206 "groups file '%s':" 207 "Authz file cannot contain any groups " 208 "when global groups are being used.", 209 path, groups_path); 210 211 /* We simply need to add the [Groups] section to the authz config. 212 */ 213 svn_config__shallow_replace_section(authz_ref->authz->cfg, 214 authz_ref->groups_cfg, 215 SVN_CONFIG_SECTION_GROUPS); 216 } 217 218 /* Make sure there are no errors in the configuration. */ 219 SVN_ERR(svn_repos__authz_validate(authz_ref->authz, authz_ref_pool)); 220 221 SVN_ERR(svn_object_pool__insert((void **)authz_p, authz_pool->object_pool, 222 authz_ref->key, authz_ref, NULL, 223 authz_ref_pool, pool)); 224 225 return SVN_NO_ERROR; 226} 227