2 * authz_pool.c : pool of authorization objects
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
13 * http://www.apache.org/licenses/LICENSE-2.0
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
21 * ====================================================================
26 #include "svn_checksum.h"
27 #include "svn_config.h"
28 #include "svn_error.h"
29 #include "svn_pools.h"
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"
41 /* Currently this structure is just a wrapper around a svn_config_t.
48 /* The wrapper object structure that we store in the object pool. It
49 * combines the authz with the underlying config structures and their
52 typedef struct authz_object_t
54 /* key = concatenation of AUTHZ_KEY and GROUPS_KEY */
57 /* keys used to identify AUTHZ_CFG and GROUPS_CFG */
58 svn_membuf_t *authz_key;
59 svn_membuf_t *groups_key;
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;
66 /* Case-sensitive config. */
70 /* Root data structure simply adding the config_pool to the basic object pool.
72 struct svn_repos__authz_pool_t
74 /* authz_object_t object storage */
75 svn_object_pool__t *object_pool;
77 /* factory and storage of (shared) configuration objects */
78 svn_repos__config_pool_t *config_pool;
81 /* Return a combination of AUTHZ_KEY and GROUPS_KEY, allocated in POOL.
82 * GROUPS_KEY may be NULL.
85 construct_key(svn_membuf_t *authz_key,
86 svn_membuf_t *groups_key,
89 svn_membuf_t *result = apr_pcalloc(pool, sizeof(*result));
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);
101 size = authz_key->size;
102 svn_membuf__create(result, size, pool);
103 memcpy(result->data, authz_key->data, authz_key->size);
110 /* Implement svn_object_pool__getter_t on authz_object_t structures.
117 return ((authz_object_t *)object)->authz;
120 /* API implementation */
123 svn_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,
128 svn_repos__authz_pool_t *result;
129 svn_object_pool__t *object_pool;
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,
135 result = apr_pcalloc(pool, sizeof(*result));
136 result->object_pool = object_pool;
137 result->config_pool = config_pool;
139 *authz_pool = result;
144 svn_repos__authz_pool_get(svn_authz_t **authz_p,
145 svn_repos__authz_pool_t *authz_pool,
147 const char *groups_path,
148 svn_boolean_t must_exist,
149 svn_repos_t *preferred_repos,
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;
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;
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;
176 /* fall back to standard implementation in case we don't have all the
177 * facts (i.e. keys). */
179 return svn_error_trace(svn_repos_authz_read2(authz_p, path, groups_path,
182 /* all keys are known and lookup is unambigious. */
183 authz_ref->key = construct_key(authz_ref->authz_key,
184 authz_ref->groups_key,
187 SVN_ERR(svn_object_pool__lookup((void **)authz_p, authz_pool->object_pool,
188 authz_ref->key, NULL, pool));
191 svn_pool_destroy(authz_ref_pool);
195 authz_ref->authz = apr_palloc(authz_ref_pool, sizeof(*authz_ref->authz));
196 authz_ref->authz->cfg = authz_ref->authz_cfg;
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 "
207 "Authz file cannot contain any groups "
208 "when global groups are being used.",
211 /* We simply need to add the [Groups] section to the authz config.
213 svn_config__shallow_replace_section(authz_ref->authz->cfg,
214 authz_ref->groups_cfg,
215 SVN_CONFIG_SECTION_GROUPS);
218 /* Make sure there are no errors in the configuration. */
219 SVN_ERR(svn_repos__authz_validate(authz_ref->authz, authz_ref_pool));
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));