~ubuntu-branches/debian/sid/subversion/sid

« back to all changes in this revision

Viewing changes to subversion/libsvn_repos/authz_pool.c

  • Committer: Package Import Robot
  • Author(s): James McCoy
  • Date: 2015-08-07 21:32:47 UTC
  • mfrom: (0.2.15) (4.1.7 experimental)
  • Revision ID: package-import@ubuntu.com-20150807213247-ozyewtmgsr6tkewl
Tags: 1.9.0-1
* Upload to unstable
* New upstream release.
  + Security fixes
    - CVE-2015-3184: Mixed anonymous/authenticated path-based authz with
      httpd 2.4
    - CVE-2015-3187: svn_repos_trace_node_locations() reveals paths hidden
      by authz
* Add >= 2.7 requirement for python-all-dev Build-Depends, needed to run
  tests.
* Remove Build-Conflicts against ruby-test-unit.  (Closes: #791844)
* Remove patches/apache_module_dependency in favor of expressing the
  dependencies in authz_svn.load/dav_svn.load.
* Build-Depend on apache2-dev (>= 2.4.16) to ensure ap_some_authn_required()
  is available when building mod_authz_svn and Depend on apache2-bin (>=
  2.4.16) for runtime support.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 */
 
43
struct 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
 */
 
52
typedef 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
 */
 
72
struct 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
 */
 
84
static svn_membuf_t *
 
85
construct_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
 */
 
112
static void *
 
113
getter(void *object,
 
114
       void *baton,
 
115
       apr_pool_t *pool)
 
116
{
 
117
  return ((authz_object_t *)object)->authz;
 
118
}
 
119
 
 
120
/* API implementation */
 
121
 
 
122
svn_error_t *
 
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,
 
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
 
 
143
svn_error_t *
 
144
svn_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
}