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"));