You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2016/12/18 08:56:25 UTC

svn commit: r1774864 - in /subversion/branches/authzperf: BRANCH-README subversion/include/private/svn_config_private.h subversion/libsvn_repos/config_file.c subversion/libsvn_subr/config.c subversion/tests/libsvn_subr/config-test.c

Author: stefan2
Date: Sun Dec 18 08:56:25 2016
New Revision: 1774864

URL: http://svn.apache.org/viewvc?rev=1774864&view=rev
Log:
On the authzperf branch:
Add support for in-registry authz under Windows.

While this is certainly a fringe use-case, there will probably be a few
installations out there where the registry was used to hold the authz
config or parts of it.  There is no compelling reason to break those
setups.

The solution is to simply use the standard config parser, serialize the
result into a string buffer and process that as if it came from a file.
If need be, this code path could later be used as a fallback for any
config parsing feature that we might have missed with the new code.

* subversion/include/private/svn_config_private.h
  (svn_config__write): Declare the new private serializer interface.

* subversion/libsvn_subr/config.c
  (svn_config__write): Implement.

* subversion/libsvn_repos/config_file.c
  (get_registry_config): New parser function, alongside "in-file" and
                         "in-repo" config support.
  (svn_repos__get_config): Add handling of registry URLs under Windows.

* subversion/tests/libsvn_subr/config-test.c
  (test_serialization): New test case for the new serializer interface.
  (test_funcs): Register new test.

* BRANCH-README
  (TODO, DONE): Update

Modified:
    subversion/branches/authzperf/BRANCH-README
    subversion/branches/authzperf/subversion/include/private/svn_config_private.h
    subversion/branches/authzperf/subversion/libsvn_repos/config_file.c
    subversion/branches/authzperf/subversion/libsvn_subr/config.c
    subversion/branches/authzperf/subversion/tests/libsvn_subr/config-test.c

Modified: subversion/branches/authzperf/BRANCH-README
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/BRANCH-README?rev=1774864&r1=1774863&r2=1774864&view=diff
==============================================================================
--- subversion/branches/authzperf/BRANCH-README (original)
+++ subversion/branches/authzperf/BRANCH-README Sun Dec 18 08:56:25 2016
@@ -14,7 +14,6 @@ TODO:
 * remove no-op escape sequences from wildcard rule segments
 * implement lookup access rights
 * correct the global <-> per-repo rule precedence to match 1.9 behavior
-* support in-registry authz again
 * use a user's accumulated "global" access rights where sufficient
 
 DONE:
@@ -44,3 +43,4 @@ DONE:
 * make models read-only such that they may be cached
 * implement global authz and filtered tree caches
 * add fast lookup path for in-repository authz files
+* support in-registry authz

Modified: subversion/branches/authzperf/subversion/include/private/svn_config_private.h
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/include/private/svn_config_private.h?rev=1774864&r1=1774863&r2=1774864&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/include/private/svn_config_private.h (original)
+++ subversion/branches/authzperf/subversion/include/private/svn_config_private.h Sun Dec 18 08:56:25 2016
@@ -32,6 +32,7 @@
 #include "svn_error.h"
 #include "svn_io.h"
 #include "svn_string.h"
+#include "svn_config.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -109,6 +110,18 @@ svn_config__parse_stream(svn_stream_t *s
                          void *constructor_baton,
                          apr_pool_t *scratch_pool);
 
+/*
+ * Write the configuration CFG to STREAM, using SCRATCH_POOL for
+ * temporary allocations.
+ *
+ * Note that option values will not be expanded and that the order
+ * of sections as well as the options within them is undefined.
+ */
+svn_error_t *
+svn_config__write(svn_stream_t *stream,
+                  const svn_config_t *cfg,
+                  apr_pool_t *scratch_pool);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */

Modified: subversion/branches/authzperf/subversion/libsvn_repos/config_file.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_repos/config_file.c?rev=1774864&r1=1774863&r2=1774864&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_repos/config_file.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_repos/config_file.c Sun Dec 18 08:56:25 2016
@@ -30,6 +30,7 @@
 
 #include "private/svn_subr_private.h"
 #include "private/svn_repos_private.h"
+#include "private/svn_config_private.h"
 
 #include "config_file.h"
 
@@ -298,6 +299,39 @@ get_file_config(svn_stream_t **stream,
   return SVN_NO_ERROR;
 }
 
+/* Read the configuration from Windows registry sub-tree PATH, return its
+ * content checksum in CHECKSUM and the content itself through *STREAM.
+ * Allocate those with the lifetime of ACCESS.
+ *
+ * Note that although we use this for registry data only, it will work with
+ * any configuration data that svn_config_read3 can process.
+ */
+static svn_error_t *
+get_registry_config(svn_stream_t **stream,
+                    svn_checksum_t **checksum,
+                    config_access_t *access,
+                    const char *path,
+                    svn_boolean_t must_exist,
+                    apr_pool_t *scratch_pool)
+{
+  svn_stringbuf_t *contents = svn_stringbuf_create_empty(access->pool);
+  svn_config_t *config;
+
+  /* Read the configuration and serialize it into CONTENTS.
+   * That copy can then be processed by the authz parser etc. */
+  SVN_ERR(svn_config_read3(&config, path, must_exist, TRUE, TRUE,
+                           scratch_pool));
+  SVN_ERR(svn_config__write(svn_stream_from_stringbuf(contents, scratch_pool),
+                            config, scratch_pool));
+
+  /* calculate MD5 over the whole file contents */
+  SVN_ERR(svn_checksum(checksum, svn_checksum_md5,
+                       contents->data, contents->len, access->pool));
+  *stream = svn_stream_from_stringbuf(contents, access->pool);
+
+  return SVN_NO_ERROR;
+}
+
 config_access_t *
 svn_repos__create_config_access(svn_repos_t *repos_hint,
                                 apr_pool_t *result_pool)
@@ -325,6 +359,12 @@ svn_repos__get_config(svn_stream_t **str
                       svn_boolean_t must_exist,
                       apr_pool_t *scratch_pool)
 {
+#ifdef WIN32
+  if (0 == strncmp(file, SVN_REGISTRY_PREFIX, SVN_REGISTRY_PREFIX_LEN))
+    SVN_ERR(get_registry_config(stream, checksum, access, path, must_exist,
+                                scratch_pool));
+  else
+#endif /* WIN32 */
   if (svn_path_is_url(path))
     SVN_ERR(get_repos_config(stream, checksum, access, path, must_exist,
                              scratch_pool));

Modified: subversion/branches/authzperf/subversion/libsvn_subr/config.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/libsvn_subr/config.c?rev=1774864&r1=1774863&r2=1774864&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/libsvn_subr/config.c (original)
+++ subversion/branches/authzperf/subversion/libsvn_subr/config.c Sun Dec 18 08:56:25 2016
@@ -1332,3 +1332,40 @@ svn_config_has_section(svn_config_t *cfg
   return NULL != get_hash_value(cfg->sections, cfg->tmp_key, section,
                                 cfg->section_names_case_sensitive);
 }
+
+svn_error_t *
+svn_config__write(svn_stream_t *stream,
+                  const struct svn_config_t *cfg,
+                  apr_pool_t *scratch_pool)
+{
+  apr_hash_index_t *section_i;
+  apr_hash_index_t *options_i;
+  apr_pool_t *section_pool = svn_pool_create(scratch_pool);
+  apr_pool_t *options_pool = svn_pool_create(scratch_pool);
+
+  for (section_i = apr_hash_first(scratch_pool, cfg->sections);
+       section_i != NULL;
+       section_i = apr_hash_next(section_i))
+    {
+      cfg_section_t *section = apr_hash_this_val(section_i);
+      svn_pool_clear(section_pool);
+      SVN_ERR(svn_stream_printf(stream, section_pool, "\n[%s]\n",
+                                section->name));
+
+      for (options_i = apr_hash_first(section_pool, section->options);
+           options_i != NULL;
+           options_i = apr_hash_next(options_i))
+        {
+          cfg_option_t *option = apr_hash_this_val(options_i);
+          svn_pool_clear(options_pool);
+          SVN_ERR(svn_stream_printf(stream, options_pool, "%s=%s\n",
+                                    option->name, option->value));
+        }
+    }
+
+  svn_pool_destroy(section_pool);
+  svn_pool_destroy(options_pool);
+
+  return SVN_NO_ERROR;
+}
+

Modified: subversion/branches/authzperf/subversion/tests/libsvn_subr/config-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/authzperf/subversion/tests/libsvn_subr/config-test.c?rev=1774864&r1=1774863&r2=1774864&view=diff
==============================================================================
--- subversion/branches/authzperf/subversion/tests/libsvn_subr/config-test.c (original)
+++ subversion/branches/authzperf/subversion/tests/libsvn_subr/config-test.c Sun Dec 18 08:56:25 2016
@@ -37,6 +37,7 @@
 #include "svn_error.h"
 #include "svn_config.h"
 #include "private/svn_subr_private.h"
+#include "private/svn_config_private.h"
 
 #include "../svn_test.h"
 
@@ -403,6 +404,60 @@ test_invalid_bom(apr_pool_t *pool)
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+test_serialization(apr_pool_t *pool)
+{
+  svn_stringbuf_t *original_content;
+  svn_stringbuf_t *written_content;
+  svn_config_t *cfg;
+
+  const struct
+    {
+      const char *section;
+      const char *option;
+      const char *value;
+    } test_data[] =
+    {
+      { "my section", "value1", "some" },
+      { "my section", "value2", "something" },
+      { "another Section", "value1", "one" },
+      { "another Section", "value2", "two" },
+      { "another Section", "value 3", "more" },
+    };
+  int i;
+
+  /* Format the original with the same formatting that the writer will use. */
+  original_content = svn_stringbuf_create("\n[my section]\n"
+                                          "value1=some\n"
+                                          "value2=%(value1)sthing\n"
+                                          "\n[another Section]\n"
+                                          "value1=one\n"
+                                          "value2=two\n"
+                                          "value 3=more\n",
+                                          pool);
+  written_content = svn_stringbuf_create_empty(pool);
+
+  SVN_ERR(svn_config_parse(&cfg,
+                           svn_stream_from_stringbuf(original_content, pool),
+                           TRUE, TRUE, pool));
+  SVN_ERR(svn_config__write(svn_stream_from_stringbuf(written_content, pool),
+                            cfg, pool));
+  SVN_ERR(svn_config_parse(&cfg,
+                           svn_stream_from_stringbuf(written_content, pool),
+                           TRUE, TRUE, pool));
+
+  /* The serialized and re-parsed config must have the expected contents. */
+  for (i = 0; i < sizeof(test_data) / sizeof(test_data[0]); ++i)
+    {
+      const char *val;
+      svn_config_get(cfg, &val, test_data[i].section, test_data[i].option,
+                     NULL);
+      SVN_TEST_STRING_ASSERT(val, test_data[i].value);
+    }
+
+  return SVN_NO_ERROR;
+}
+
 /*
    ====================================================================
    If you add a new test to this file, update this array.
@@ -437,6 +492,8 @@ static struct svn_test_descriptor_t test
                        "test variable expansion"),
     SVN_TEST_PASS2(test_invalid_bom,
                    "test parsing config file with invalid BOM"),
+    SVN_TEST_PASS2(test_serialization,
+                   "test writing a config"),
     SVN_TEST_NULL
   };