You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ph...@apache.org on 2013/02/15 12:50:33 UTC

svn commit: r1446542 - /subversion/trunk/subversion/svnserve/serve.c

Author: philip
Date: Fri Feb 15 11:50:32 2013
New Revision: 1446542

URL: http://svn.apache.org/r1446542
Log:
Support freezing multiple repositories in libsvn_repos and
make svnadmin support both:

  svnadmin freeze repository command arguments...
  svnadmin freeze -F file_of_repositories command arguments...

* subversion/include/svn_repos.h
  (svn_repos_freeze): Change parameter to array.

* subversion/libsvn_repos/repos.c
  (struct freeze_baton_t): New.
  (multi_freeze): New.
  (svn_repos_freeze): Change parameter to array, call multi_freeze.

* subversion/svnadmin/svnadmin.c
  (options_table): Add -F.
  (cmd_table): Add -F to freeze.
  (subcommand_freeze): Handle one repository or a file of repositories.
  (sub_main): Parse -F, don't expect explict repository with -F.

Modified:
    subversion/trunk/subversion/svnserve/serve.c

Modified: subversion/trunk/subversion/svnserve/serve.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svnserve/serve.c?rev=1446542&r1=1446541&r2=1446542&view=diff
==============================================================================
--- subversion/trunk/subversion/svnserve/serve.c (original)
+++ subversion/trunk/subversion/svnserve/serve.c Fri Feb 15 11:50:32 2013
@@ -97,6 +97,10 @@ typedef struct fs_warning_baton_t {
   apr_pool_t *pool;
 } fs_warning_baton_t;
 
+typedef struct authz_baton_t {
+  server_baton_t *server;
+  svn_ra_svn_conn_t *conn;
+} authz_baton_t;
 
 /* Write LEN bytes of ERRSTR to LOG_FILE with svn_io_file_write(). */
 static svn_error_t *
@@ -221,6 +225,39 @@ static svn_error_t *log_command(server_b
   return log_write(b->log_file, line, nbytes, pool);
 }
 
+/* Log an authz failure */
+static svn_error_t *
+log_authz_denied(const char *path,
+                 svn_repos_authz_access_t required,
+                 server_baton_t *b,
+                 svn_ra_svn_conn_t *conn,
+                 apr_pool_t *pool)
+{
+  const char *timestr, *remote_host, *line;
+
+  if (b->log_file == NULL)
+    return SVN_NO_ERROR;
+
+  if (!b->user)
+    return SVN_NO_ERROR;
+
+  timestr = svn_time_to_cstring(apr_time_now(), pool);
+  remote_host = svn_ra_svn_conn_remote_host(conn);
+
+  line = apr_psprintf(pool, "%" APR_PID_T_FMT 
+                      " %s %s %s %s Authorization Failed %s%s %s" APR_EOL_STR,
+                      getpid(), timestr,
+                      (remote_host ? remote_host : "-"),
+                      (b->user ? b->user : "-"),
+                      b->repos_name,
+                      (required & svn_authz_recursive ? "recursive " : ""),
+                      (required & svn_authz_write ? "write" : "read"),
+                      (path && path[0] ? path : "/"));
+
+  return log_write(b->log_file, line, strlen(line), pool);
+}
+
+
 svn_error_t *load_pwdb_config(server_baton_t *server,
                               svn_ra_svn_conn_t *conn,
                               apr_pool_t *pool)
@@ -401,6 +438,7 @@ static svn_error_t *authz_check_access(s
                                        const char *path,
                                        svn_repos_authz_access_t required,
                                        server_baton_t *b,
+                                       svn_ra_svn_conn_t *conn,
                                        apr_pool_t *pool)
 {
   /* If authz cannot be performed, grant access.  This is NOT the same
@@ -435,9 +473,13 @@ static svn_error_t *authz_check_access(s
       b->authz_user = authz_user;
     }
 
-  return svn_repos_authz_check_access(b->authzdb, b->authz_repos_name,
-                                      path, b->authz_user, required,
-                                      allowed, pool);
+  SVN_ERR(svn_repos_authz_check_access(b->authzdb, b->authz_repos_name,
+                                       path, b->authz_user, required,
+                                       allowed, pool));
+  if (!*allowed)
+    SVN_ERR(log_authz_denied(path, required, b, conn, pool));
+
+  return SVN_NO_ERROR;
 }
 
 /* Set *ALLOWED to TRUE if PATH is readable by the user described in
@@ -450,9 +492,10 @@ static svn_error_t *authz_check_access_c
                                           void *baton,
                                           apr_pool_t *pool)
 {
-  server_baton_t *sb = baton;
+  authz_baton_t *sb = baton;
 
-  return authz_check_access(allowed, path, svn_authz_read, sb, pool);
+  return authz_check_access(allowed, path, svn_authz_read,
+                            sb->server, sb->conn, pool);
 }
 
 /* If authz is enabled in the specified BATON, return a read authorization
@@ -476,9 +519,10 @@ static svn_error_t *authz_commit_cb(svn_
                                     void *baton,
                                     apr_pool_t *pool)
 {
-  server_baton_t *sb = baton;
+  authz_baton_t *sb = baton;
 
-  return authz_check_access(allowed, path, required, sb, pool);
+  return authz_check_access(allowed, path, required,
+                            sb->server, sb->conn, pool);
 }
 
 
@@ -687,7 +731,7 @@ static svn_boolean_t lookup_access(apr_p
   svn_error_t *err;
 
   /* Get authz's opinion on the access. */
-  err = authz_check_access(&authorized, path, required, baton, pool);
+  err = authz_check_access(&authorized, path, required, baton, conn, pool);
 
   /* If an error made lookup fail, deny access. */
   if (err)
@@ -902,6 +946,10 @@ static svn_error_t *accept_report(svn_bo
   void *edit_baton, *report_baton;
   report_driver_baton_t rb;
   svn_error_t *err;
+  authz_baton_t ab;
+
+  ab.server = b;
+  ab.conn = conn;
 
   /* Make an svn_repos report baton.  Tell it to drive the network editor
    * when the report is complete. */
@@ -912,7 +960,7 @@ static svn_error_t *accept_report(svn_bo
                                       send_copyfrom_args,
                                       editor, edit_baton,
                                       authz_check_access_cb_func(b),
-                                      b, svn_ra_svn_zero_copy_limit(conn),
+                                      &ab, svn_ra_svn_zero_copy_limit(conn),
                                       pool));
 
   rb.sb = b;
@@ -988,7 +1036,7 @@ static svn_error_t *write_lock(svn_ra_sv
 static svn_error_t *
 get_props(apr_hash_t **props,
           apr_array_header_t **iprops,
-          server_baton_t *b,
+          authz_baton_t *b,
           svn_fs_root_t *root,
           const char *path,
           apr_pool_t *pool)
@@ -1025,9 +1073,10 @@ get_props(apr_hash_t **props,
   /* Get any inherited properties the user is authorized to. */
   if (iprops)
     {
-      SVN_ERR(svn_repos_fs_get_inherited_props(iprops, root, path, NULL,
-                                               authz_check_access_cb_func(b),
-                                               b, pool, pool));
+      SVN_ERR(svn_repos_fs_get_inherited_props(
+                iprops, root, path, NULL,
+                authz_check_access_cb_func(b->server),
+                b, pool, pool));
     }
 
   return SVN_NO_ERROR;
@@ -1094,13 +1143,18 @@ static svn_error_t *do_change_rev_prop(s
                                        const svn_string_t *value,
                                        apr_pool_t *pool)
 {
+  authz_baton_t ab;
+
+  ab.server = b;
+  ab.conn = conn;
+
   SVN_ERR(must_have_access(conn, pool, b, svn_authz_write, NULL, FALSE));
   SVN_ERR(log_command(b, conn, pool, "%s",
                       svn_log__change_rev_prop(rev, name, pool)));
   SVN_CMD_ERR(svn_repos_fs_change_rev_prop4(b->repos, rev, b->user,
                                             name, old_value_p, value,
                                             TRUE, TRUE,
-                                            authz_check_access_cb_func(b), b,
+                                            authz_check_access_cb_func(b), &ab,
                                             pool));
   SVN_ERR(svn_ra_svn_write_cmd_response(conn, pool, ""));
 
@@ -1167,13 +1221,17 @@ static svn_error_t *rev_proplist(svn_ra_
   server_baton_t *b = baton;
   svn_revnum_t rev;
   apr_hash_t *props;
+  authz_baton_t ab;
+
+  ab.server = b;
+  ab.conn = conn;
 
   SVN_ERR(svn_ra_svn_parse_tuple(params, pool, "r", &rev));
   SVN_ERR(log_command(b, conn, pool, "%s", svn_log__rev_proplist(rev, pool)));
 
   SVN_ERR(trivial_auth_request(conn, pool, b));
   SVN_CMD_ERR(svn_repos_fs_revision_proplist(&props, b->repos, rev,
-                                             authz_check_access_cb_func(b), b,
+                                             authz_check_access_cb_func(b), &ab,
                                              pool));
   SVN_ERR(svn_ra_svn_write_tuple(conn, pool, "w((!", "success"));
   SVN_ERR(svn_ra_svn_write_proplist(conn, pool, props));
@@ -1188,6 +1246,10 @@ static svn_error_t *rev_prop(svn_ra_svn_
   svn_revnum_t rev;
   const char *name;
   svn_string_t *value;
+  authz_baton_t ab;
+
+  ab.server = b;
+  ab.conn = conn;
 
   SVN_ERR(svn_ra_svn_parse_tuple(params, pool, "rc", &rev, &name));
   SVN_ERR(log_command(b, conn, pool, "%s",
@@ -1195,7 +1257,7 @@ static svn_error_t *rev_prop(svn_ra_svn_
 
   SVN_ERR(trivial_auth_request(conn, pool, b));
   SVN_CMD_ERR(svn_repos_fs_revision_prop(&value, b->repos, rev, name,
-                                         authz_check_access_cb_func(b), b,
+                                         authz_check_access_cb_func(b), &ab,
                                          pool));
   SVN_ERR(svn_ra_svn_write_cmd_response(conn, pool, "(?s)", value));
   return SVN_NO_ERROR;
@@ -1334,6 +1396,10 @@ static svn_error_t *commit(svn_ra_svn_co
   svn_boolean_t aborted;
   commit_callback_baton_t ccb;
   svn_revnum_t new_rev;
+  authz_baton_t ab;
+
+  ab.server = b;
+  ab.conn = conn;
 
   if (params->nelts == 1)
     {
@@ -1391,7 +1457,7 @@ static svn_error_t *commit(svn_ra_svn_co
                svn_path_uri_decode(b->repos_url, pool),
                b->fs_path->data, revprop_table,
                commit_done, &ccb,
-               authz_commit_cb, baton, pool));
+               authz_commit_cb, &ab, pool));
   SVN_ERR(svn_ra_svn_write_cmd_response(conn, pool, ""));
   SVN_ERR(svn_ra_svn_drive_editor(conn, pool, editor, edit_baton, &aborted));
   if (!aborted)
@@ -1439,6 +1505,10 @@ static svn_error_t *get_file(svn_ra_svn_
   svn_checksum_t *checksum;
   svn_error_t *err, *write_err;
   int i;
+  authz_baton_t ab;
+
+  ab.server = b;
+  ab.conn = conn;
 
   /* Parse arguments. */
   SVN_ERR(svn_ra_svn_parse_tuple(params, pool, "c(?r)bb?B", &path, &rev,
@@ -1465,7 +1535,7 @@ static svn_error_t *get_file(svn_ra_svn_
                                    full_path, TRUE, pool));
   hex_digest = svn_checksum_to_cstring_display(checksum, pool);
   if (want_props || wants_inherited_props)
-    SVN_CMD_ERR(get_props(&props, &inherited_props, b, root, full_path,
+    SVN_CMD_ERR(get_props(&props, &inherited_props, &ab, root, full_path,
                           pool));
   if (want_contents)
     SVN_CMD_ERR(svn_fs_file_contents(&contents, root, full_path, pool));
@@ -1549,6 +1619,10 @@ static svn_error_t *get_dir(svn_ra_svn_c
   apr_array_header_t *dirent_fields_list = NULL;
   svn_ra_svn_item_t *elt;
   int i;
+  authz_baton_t ab;
+
+  ab.server = b;
+  ab.conn = conn;
 
   SVN_ERR(svn_ra_svn_parse_tuple(params, pool, "c(?r)bb?l?B", &path, &rev,
                                  &want_props, &want_contents,
@@ -1607,7 +1681,7 @@ static svn_error_t *get_dir(svn_ra_svn_c
   /* Fetch the directory's explicit and/or inherited properties
      if requested. */
   if (want_props || wants_inherited_props)
-    SVN_CMD_ERR(get_props(&props, &inherited_props, b, root, full_path,
+    SVN_CMD_ERR(get_props(&props, &inherited_props, &ab, root, full_path,
                           pool));
 
   /* Begin response ... */
@@ -1934,6 +2008,10 @@ static svn_error_t *get_mergeinfo(svn_ra
   svn_mergeinfo_inheritance_t inherit;
   svn_boolean_t include_descendants;
   apr_pool_t *iterpool;
+  authz_baton_t ab;
+
+  ab.server = b;
+  ab.conn = conn;
 
   SVN_ERR(svn_ra_svn_parse_tuple(params, pool, "l(?r)wb", &paths, &rev,
                                  &inherit_word, &include_descendants));
@@ -1964,7 +2042,7 @@ static svn_error_t *get_mergeinfo(svn_ra
                                          canonical_paths, rev,
                                          inherit,
                                          include_descendants,
-                                         authz_check_access_cb_func(b), b,
+                                         authz_check_access_cb_func(b), &ab,
                                          pool));
   SVN_ERR(svn_mergeinfo__remove_prefix_from_catalog(&mergeinfo, mergeinfo,
                                                     b->fs_path->data, pool));
@@ -2073,6 +2151,10 @@ static svn_error_t *log_cmd(svn_ra_svn_c
   int i;
   apr_uint64_t limit, include_merged_revs_param;
   log_baton_t lb;
+  authz_baton_t ab;
+
+  ab.server = b;
+  ab.conn = conn;
 
   SVN_ERR(svn_ra_svn_parse_tuple(params, pool, "l(?r)(?r)bb?n?Bwl", &paths,
                                  &start_rev, &end_rev, &send_changed_paths,
@@ -2143,7 +2225,7 @@ static svn_error_t *log_cmd(svn_ra_svn_c
   err = svn_repos_get_logs4(b->repos, full_paths, start_rev, end_rev,
                             (int) limit, send_changed_paths, strict_node,
                             include_merged_revisions, revprops,
-                            authz_check_access_cb_func(b), b, log_receiver,
+                            authz_check_access_cb_func(b), &ab, log_receiver,
                             &lb, pool);
 
   write_err = svn_ra_svn_write_word(conn, pool, "done");
@@ -2247,6 +2329,10 @@ static svn_error_t *get_locations(svn_ra
   svn_revnum_t peg_revision;
   apr_hash_t *fs_locations;
   const char *abs_path;
+  authz_baton_t ab;
+
+  ab.server = b;
+  ab.conn = conn;
 
   /* Parse the arguments. */
   SVN_ERR(svn_ra_svn_parse_tuple(params, pool, "crl", &relative_path,
@@ -2281,7 +2367,8 @@ static svn_error_t *get_locations(svn_ra
 
   err = svn_repos_trace_node_locations(b->fs, &fs_locations, abs_path,
                                        peg_revision, location_revisions,
-                                       authz_check_access_cb_func(b), b, pool);
+                                       authz_check_access_cb_func(b), &ab,
+                                       pool);
 
   /* Now, write the results to the connection. */
   if (!err)
@@ -2336,6 +2423,10 @@ static svn_error_t *get_location_segment
   svn_revnum_t peg_revision, start_rev, end_rev;
   const char *relative_path;
   const char *abs_path;
+  authz_baton_t ab;
+
+  ab.server = b;
+  ab.conn = conn;
 
   /* Parse the arguments. */
   SVN_ERR(svn_ra_svn_parse_tuple(params, pool, "c(?r)(?r)(?r)",
@@ -2380,7 +2471,7 @@ static svn_error_t *get_location_segment
   err = svn_repos_node_location_segments(b->repos, abs_path,
                                          peg_revision, start_rev, end_rev,
                                          gls_receiver, (void *)conn,
-                                         authz_check_access_cb_func(b), b,
+                                         authz_check_access_cb_func(b), &ab,
                                          pool);
   write_err = svn_ra_svn_write_word(conn, pool, "done");
   if (write_err)
@@ -2474,6 +2565,10 @@ static svn_error_t *get_file_revs(svn_ra
   const char *full_path;
   apr_uint64_t include_merged_revs_param;
   svn_boolean_t include_merged_revisions;
+  authz_baton_t ab;
+
+  ab.server = b;
+  ab.conn = conn;
 
   /* Parse arguments. */
   SVN_ERR(svn_ra_svn_parse_tuple(params, pool, "c(?r)(?r)?B",
@@ -2498,7 +2593,7 @@ static svn_error_t *get_file_revs(svn_ra
 
   err = svn_repos_get_file_revs2(b->repos, full_path, start_rev, end_rev,
                                  include_merged_revisions,
-                                 authz_check_access_cb_func(b), b,
+                                 authz_check_access_cb_func(b), &ab,
                                  file_rev_handler, &frb, pool);
   write_err = svn_ra_svn_write_word(conn, pool, "done");
   if (write_err)
@@ -2796,6 +2891,10 @@ static svn_error_t *get_locks(svn_ra_svn
   apr_hash_t *locks;
   apr_hash_index_t *hi;
   svn_error_t *err;
+  authz_baton_t ab;
+
+  ab.server = b;
+  ab.conn = conn;
 
   SVN_ERR(svn_ra_svn_parse_tuple(params, pool, "c?(?w)", &path, &depth_word));
 
@@ -2818,7 +2917,8 @@ static svn_error_t *get_locks(svn_ra_svn
   SVN_ERR(log_command(b, conn, pool, "get-locks %s",
                       svn_path_uri_encode(full_path, pool)));
   SVN_CMD_ERR(svn_repos_fs_get_locks2(&locks, b->repos, full_path, depth,
-                                      authz_check_access_cb_func(b), b, pool));
+                                      authz_check_access_cb_func(b), &ab,
+                                      pool));
 
   SVN_ERR(svn_ra_svn_write_tuple(conn, pool, "w((!", "success"));
   for (hi = apr_hash_first(pool, locks); hi; hi = apr_hash_next(hi))
@@ -2843,6 +2943,10 @@ static svn_error_t *replay_one_revision(
   void *edit_baton;
   svn_fs_root_t *root;
   svn_error_t *err;
+  authz_baton_t ab;
+
+  ab.server = b;
+  ab.conn = conn;
 
   SVN_ERR(log_command(b, conn, pool,
                       svn_log__replay(b->fs_path->data, low_water_mark,
@@ -2855,7 +2959,7 @@ static svn_error_t *replay_one_revision(
   if (! err)
     err = svn_repos_replay2(root, b->fs_path->data, low_water_mark,
                             send_deltas, editor, edit_baton,
-                            authz_check_access_cb_func(b), b, pool);
+                            authz_check_access_cb_func(b), &ab, pool);
 
   if (err)
     svn_error_clear(editor->abort_edit(edit_baton, pool));
@@ -2892,6 +2996,10 @@ static svn_error_t *replay_range(svn_ra_
   svn_boolean_t send_deltas;
   server_baton_t *b = baton;
   apr_pool_t *iterpool;
+  authz_baton_t ab;
+
+  ab.server = b;
+  ab.conn = conn;
 
   SVN_ERR(svn_ra_svn_parse_tuple(params, pool, "rrrb", &start_rev,
                                  &end_rev, &low_water_mark,
@@ -2908,7 +3016,7 @@ static svn_error_t *replay_range(svn_ra_
 
       SVN_CMD_ERR(svn_repos_fs_revision_proplist(&props, b->repos, rev,
                                                  authz_check_access_cb_func(b),
-                                                 b,
+                                                 &ab,
                                                  iterpool));
       SVN_ERR(svn_ra_svn_write_tuple(conn, iterpool, "w(!", "revprops"));
       SVN_ERR(svn_ra_svn_write_proplist(conn, iterpool, props));
@@ -2962,6 +3070,10 @@ get_inherited_props(svn_ra_svn_conn_t *c
   apr_array_header_t *inherited_props;
   int i;
   apr_pool_t *iterpool = svn_pool_create(pool);
+  authz_baton_t ab;
+
+  ab.server = b;
+  ab.conn = conn;
 
   /* Parse arguments. */
   SVN_ERR(svn_ra_svn_parse_tuple(params, iterpool, "c(?r)", &path, &rev));
@@ -2983,7 +3095,7 @@ get_inherited_props(svn_ra_svn_conn_t *c
 
   /* Fetch the properties and a stream for the contents. */
   SVN_CMD_ERR(svn_fs_revision_root(&root, b->fs, rev, iterpool));
-  SVN_CMD_ERR(get_props(NULL, &inherited_props, b, root, full_path, pool));
+  SVN_CMD_ERR(get_props(NULL, &inherited_props, &ab, root, full_path, pool));
 
   /* Send successful command response with revision and props. */
   SVN_ERR(svn_ra_svn_write_tuple(conn, iterpool, "w(!", "success"));