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

« back to all changes in this revision

Viewing changes to subversion/libsvn_repos/authz.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:
35
35
#include "svn_config.h"
36
36
#include "svn_ctype.h"
37
37
#include "private/svn_fspath.h"
 
38
#include "private/svn_repos_private.h"
38
39
#include "repos.h"
39
40
 
40
41
 
76
77
                           enumerator, if any. */
77
78
};
78
79
 
79
 
/* Currently this structure is just a wrapper around a
80
 
   svn_config_t. */
 
80
/* Currently this structure is just a wrapper around a svn_config_t.
 
81
   Please update authz_pool if you modify this structure. */
81
82
struct svn_authz_t
82
83
{
83
84
  svn_config_t *cfg;
351
352
  baton.user = user;
352
353
 
353
354
  /* Try to locate a repository-specific block first. */
354
 
  qualified_path = apr_pstrcat(pool, repos_name, ":", path, (char *)NULL);
 
355
  qualified_path = apr_pstrcat(pool, repos_name, ":", path, SVN_VA_NULL);
355
356
  svn_config_enumerate2(cfg, qualified_path,
356
357
                        authz_parse_line, &baton, pool);
357
358
 
394
395
  baton.required_access = required_access;
395
396
  baton.repos_path = path;
396
397
  baton.qualified_repos_path = apr_pstrcat(pool, repos_name,
397
 
                                           ":", path, (char *)NULL);
 
398
                                           ":", path, SVN_VA_NULL);
398
399
  /* Default to access granted if no rules say otherwise. */
399
400
  baton.access = TRUE;
400
401
 
453
454
  baton.access = FALSE; /* Deny access by default. */
454
455
  baton.repos_path = "/";
455
456
  baton.qualified_repos_path = apr_pstrcat(pool, repos_name,
456
 
                                           ":/", (char *)NULL);
 
457
                                           ":/", SVN_VA_NULL);
457
458
 
458
459
  /* We could have used svn_config_enumerate2 for "repos_name:/".
459
460
   * However, this requires access for root explicitly (which the user
748
749
}
749
750
 
750
751
 
751
 
/* Walk the configuration in AUTHZ looking for any errors. */
752
 
static svn_error_t *
753
 
authz_validate(svn_authz_t *authz, apr_pool_t *pool)
 
752
svn_error_t *
 
753
svn_repos__authz_validate(svn_authz_t *authz, apr_pool_t *pool)
754
754
{
755
755
  struct authz_validate_baton baton = { 0 };
756
756
 
771
771
 *
772
772
 * If DIRENT cannot be parsed as a config file then an error is returned.  The
773
773
 * contents of CFG_P is then undefined.  If MUST_EXIST is TRUE, a missing
774
 
 * authz file is also an error.
 
774
 * authz file is also an error.  The CASE_SENSITIVE controls the lookup
 
775
 * behavior for section and option names alike.
775
776
 *
776
777
 * SCRATCH_POOL will be used for temporary allocations. */
777
778
static svn_error_t *
778
 
authz_retrieve_config_repo(svn_config_t **cfg_p, const char *dirent,
779
 
                          svn_boolean_t must_exist,
780
 
                          apr_pool_t *result_pool, apr_pool_t *scratch_pool)
 
779
authz_retrieve_config_repo(svn_config_t **cfg_p,
 
780
                           const char *dirent,
 
781
                           svn_boolean_t must_exist,
 
782
                           svn_boolean_t case_sensitive,
 
783
                           apr_pool_t *result_pool,
 
784
                           apr_pool_t *scratch_pool)
781
785
{
782
786
  svn_error_t *err;
783
787
  svn_repos_t *repos;
796
800
                             "Unable to find repository at '%s'", dirent);
797
801
 
798
802
  /* Attempt to open a repository at repos_root_dirent. */
799
 
  SVN_ERR(svn_repos_open2(&repos, repos_root_dirent, NULL, scratch_pool));
 
803
  SVN_ERR(svn_repos_open3(&repos, repos_root_dirent, NULL, scratch_pool,
 
804
                          scratch_pool));
800
805
 
801
806
  fs_path = &dirent[strlen(repos_root_dirent)];
802
807
 
824
829
    {
825
830
      if (!must_exist)
826
831
        {
827
 
          SVN_ERR(svn_config_create2(cfg_p, TRUE, TRUE, result_pool));
 
832
          SVN_ERR(svn_config_create2(cfg_p, case_sensitive, case_sensitive,
 
833
                                     result_pool));
828
834
          return SVN_NO_ERROR;
829
835
        }
830
836
      else
842
848
    }
843
849
 
844
850
  SVN_ERR(svn_fs_file_contents(&contents, root, fs_path, scratch_pool));
845
 
  err = svn_config_parse(cfg_p, contents, TRUE, TRUE, result_pool);
 
851
  err = svn_config_parse(cfg_p, contents, case_sensitive, case_sensitive,
 
852
                         result_pool);
846
853
 
847
854
  /* Add the URL to the error stack since the parser doesn't have it. */
848
855
  if (err != SVN_NO_ERROR)
853
860
  return SVN_NO_ERROR;
854
861
}
855
862
 
856
 
/* Given a PATH which might be a relative repo URL (^/), an absolute
857
 
 * local repo URL (file://), an absolute path outside of the repo
858
 
 * or a location in the Windows registry.
859
 
 *
860
 
 * Retrieve the configuration data that PATH points at and parse it into
861
 
 * CFG_P allocated in POOL.
862
 
 *
863
 
 * If PATH cannot be parsed as a config file then an error is returned.  The
864
 
 * contents of CFG_P is then undefined.  If MUST_EXIST is TRUE, a missing
865
 
 * authz file is also an error.
866
 
 *
867
 
 * REPOS_ROOT points at the root of the repos you are
868
 
 * going to apply the authz against, can be NULL if you are sure that you
869
 
 * don't have a repos relative URL in PATH. */
870
 
static svn_error_t *
871
 
authz_retrieve_config(svn_config_t **cfg_p, const char *path,
872
 
                      svn_boolean_t must_exist, apr_pool_t *pool)
 
863
svn_error_t *
 
864
svn_repos__retrieve_config(svn_config_t **cfg_p,
 
865
                           const char *path,
 
866
                           svn_boolean_t must_exist,
 
867
                           svn_boolean_t case_sensitive,
 
868
                           apr_pool_t *pool)
873
869
{
874
870
  if (svn_path_is_url(path))
875
871
    {
880
876
      err = svn_uri_get_dirent_from_file_url(&dirent, path, scratch_pool);
881
877
 
882
878
      if (err == SVN_NO_ERROR)
883
 
        err = authz_retrieve_config_repo(cfg_p, dirent, must_exist, pool,
884
 
                                         scratch_pool);
 
879
        err = authz_retrieve_config_repo(cfg_p, dirent, must_exist,
 
880
                                         case_sensitive, pool, scratch_pool);
885
881
 
886
882
      /* Close the repos and streams we opened. */
887
883
      svn_pool_destroy(scratch_pool);
891
887
  else
892
888
    {
893
889
      /* Outside of repo file or Windows registry*/
894
 
      SVN_ERR(svn_config_read3(cfg_p, path, must_exist, TRUE, TRUE, pool));
 
890
      SVN_ERR(svn_config_read3(cfg_p, path, must_exist, case_sensitive,
 
891
                               case_sensitive, pool));
895
892
    }
896
893
 
897
894
  return SVN_NO_ERROR;
942
939
 
943
940
  /* Load the authz file */
944
941
  if (accept_urls)
945
 
    SVN_ERR(authz_retrieve_config(&authz->cfg, path, must_exist, pool));
 
942
    SVN_ERR(svn_repos__retrieve_config(&authz->cfg, path, must_exist, TRUE,
 
943
                                       pool));
946
944
  else
947
 
    SVN_ERR(svn_config_read3(&authz->cfg, path, must_exist, TRUE, TRUE, pool));
 
945
    SVN_ERR(svn_config_read3(&authz->cfg, path, must_exist, TRUE, TRUE,
 
946
                             pool));
948
947
 
949
948
  if (groups_path)
950
949
    {
953
952
 
954
953
      /* Load the groups file */
955
954
      if (accept_urls)
956
 
        SVN_ERR(authz_retrieve_config(&groups_cfg, groups_path, must_exist,
957
 
                                      pool));
 
955
        SVN_ERR(svn_repos__retrieve_config(&groups_cfg, groups_path,
 
956
                                           must_exist, TRUE, pool));
958
957
      else
959
958
        SVN_ERR(svn_config_read3(&groups_cfg, groups_path, must_exist,
960
959
                                 TRUE, TRUE, pool));
971
970
    }
972
971
 
973
972
  /* Make sure there are no errors in the configuration. */
974
 
  SVN_ERR(authz_validate(authz, pool));
 
973
  SVN_ERR(svn_repos__authz_validate(authz, pool));
975
974
 
976
975
  *authz_p = authz;
977
976
  return SVN_NO_ERROR;
1011
1010
    }
1012
1011
 
1013
1012
  /* Make sure there are no errors in the configuration. */
1014
 
  SVN_ERR(authz_validate(authz, pool));
 
1013
  SVN_ERR(svn_repos__authz_validate(authz, pool));
1015
1014
 
1016
1015
  *authz_p = authz;
1017
1016
  return SVN_NO_ERROR;