diff options
Diffstat (limited to 'subversion/mod_dav_svn/lock.c')
-rw-r--r-- | subversion/mod_dav_svn/lock.c | 69 |
1 files changed, 50 insertions, 19 deletions
diff --git a/subversion/mod_dav_svn/lock.c b/subversion/mod_dav_svn/lock.c index c74fec9..68d6de5 100644 --- a/subversion/mod_dav_svn/lock.c +++ b/subversion/mod_dav_svn/lock.c @@ -28,6 +28,7 @@ #include <http_log.h> #include <mod_dav.h> +#include "svn_hash.h" #include "svn_fs.h" #include "svn_repos.h" #include "svn_dav.h" @@ -142,6 +143,8 @@ unescape_xml(const char **output, if (apr_err) { char errbuf[1024]; + + errbuf[0] = '\0'; (void)apr_xml_parser_geterror(xml_parser, errbuf, sizeof(errbuf)); return dav_svn__new_error(pool, HTTP_INTERNAL_SERVER_ERROR, DAV_ERR_LOCK_SAVE_LOCK, errbuf); @@ -149,7 +152,7 @@ unescape_xml(const char **output, apr_xml_to_text(pool, xml_doc->root, APR_XML_X2T_INNER, xml_doc->namespaces, NULL, output, NULL); - return SVN_NO_ERROR; + return NULL; } @@ -450,7 +453,8 @@ get_locks(dav_lockdb *lockdb, lock. For the --force case, this is required and for the non-force case, we allow the filesystem to produce a better error for svn clients. */ - if (info->r->method_number == M_LOCK) + if (info->r->method_number == M_LOCK + && resource->info->repos->is_svn_client) { *locks = NULL; return 0; @@ -591,7 +595,8 @@ has_locks(dav_lockdb *lockdb, const dav_resource *resource, int *locks_present) lock. For the --force case, this is required and for the non-force case, we allow the filesystem to produce a better error for svn clients. */ - if (info->r->method_number == M_LOCK) + if (info->r->method_number == M_LOCK + && resource->info->repos->is_svn_client) { *locks_present = 0; return 0; @@ -640,6 +645,19 @@ append_locks(dav_lockdb *lockdb, svn_lock_t *slock; svn_error_t *serr; dav_error *derr; + dav_svn_repos *repos = resource->info->repos; + + /* We don't allow anonymous locks */ + if (! repos->username) + return dav_svn__new_error(resource->pool, HTTP_NOT_IMPLEMENTED, + DAV_ERR_LOCK_SAVE_LOCK, + "Anonymous lock creation is not allowed."); + + /* Not a path in the repository so can't lock it. */ + if (! resource->info->repos_path) + return dav_svn__new_error(resource->pool, HTTP_BAD_REQUEST, + DAV_ERR_LOCK_SAVE_LOCK, + "Attempted to lock path not in repository."); /* If the resource's fs path is unreadable, we don't allow a lock to be created on it. */ @@ -663,11 +681,10 @@ append_locks(dav_lockdb *lockdb, svn_fs_txn_t *txn; svn_fs_root_t *txn_root; const char *conflict_msg; - dav_svn_repos *repos = resource->info->repos; apr_hash_t *revprop_table = apr_hash_make(resource->pool); - apr_hash_set(revprop_table, SVN_PROP_REVISION_AUTHOR, - APR_HASH_KEY_STRING, svn_string_create(repos->username, - resource->pool)); + svn_hash_sets(revprop_table, + SVN_PROP_REVISION_AUTHOR, + svn_string_create(repos->username, resource->pool)); if (resource->info->repos->is_svn_client) return dav_svn__new_error(resource->pool, HTTP_METHOD_NOT_ALLOWED, @@ -741,14 +758,14 @@ append_locks(dav_lockdb *lockdb, /* Convert the dav_lock into an svn_lock_t. */ derr = dav_lock_to_svn_lock(&slock, lock, resource->info->repos_path, - info, resource->info->repos->is_svn_client, + info, repos->is_svn_client, resource->pool); if (derr) return derr; /* Now use the svn_lock_t to actually perform the lock. */ serr = svn_repos_fs_lock(&slock, - resource->info->repos->repos, + repos->repos, slock->path, slock->token, slock->comment, @@ -761,14 +778,21 @@ append_locks(dav_lockdb *lockdb, if (serr && serr->apr_err == SVN_ERR_FS_NO_USER) { svn_error_clear(serr); - return dav_svn__new_error(resource->pool, HTTP_UNAUTHORIZED, + return dav_svn__new_error(resource->pool, HTTP_NOT_IMPLEMENTED, DAV_ERR_LOCK_SAVE_LOCK, "Anonymous lock creation is not allowed."); } + else if (serr && (serr->apr_err == SVN_ERR_REPOS_HOOK_FAILURE || + serr->apr_err == SVN_ERR_FS_NO_SUCH_LOCK || + serr->apr_err == SVN_ERR_FS_LOCK_EXPIRED || + SVN_ERR_IS_LOCK_ERROR(serr))) + return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR, + "Failed to create new lock.", + resource->pool); else if (serr) - return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR, - "Failed to create new lock.", - resource->pool); + return dav_svn__sanitize_error(serr, "Failed to create new lock.", + HTTP_INTERNAL_SERVER_ERROR, + resource->info->r); /* A standard webdav LOCK response doesn't include any information @@ -864,7 +888,7 @@ remove_lock(dav_lockdb *lockdb, if (serr && serr->apr_err == SVN_ERR_FS_NO_USER) { svn_error_clear(serr); - return dav_svn__new_error(resource->pool, HTTP_UNAUTHORIZED, + return dav_svn__new_error(resource->pool, HTTP_NOT_IMPLEMENTED, DAV_ERR_LOCK_SAVE_LOCK, "Anonymous lock removal is not allowed."); } @@ -931,7 +955,7 @@ refresh_locks(dav_lockdb *lockdb, current lock on the incoming resource? */ if ((! slock) || (strcmp(token->uuid_str, slock->token) != 0)) - return dav_svn__new_error(resource->pool, HTTP_UNAUTHORIZED, + return dav_svn__new_error(resource->pool, HTTP_PRECONDITION_FAILED, DAV_ERR_LOCK_SAVE_LOCK, "Lock refresh request doesn't match existing " "lock."); @@ -952,14 +976,21 @@ refresh_locks(dav_lockdb *lockdb, if (serr && serr->apr_err == SVN_ERR_FS_NO_USER) { svn_error_clear(serr); - return dav_svn__new_error(resource->pool, HTTP_UNAUTHORIZED, + return dav_svn__new_error(resource->pool, HTTP_NOT_IMPLEMENTED, DAV_ERR_LOCK_SAVE_LOCK, "Anonymous lock refreshing is not allowed."); } + else if (serr && (serr->apr_err == SVN_ERR_REPOS_HOOK_FAILURE || + serr->apr_err == SVN_ERR_FS_NO_SUCH_LOCK || + serr->apr_err == SVN_ERR_FS_LOCK_EXPIRED || + SVN_ERR_IS_LOCK_ERROR(serr))) + return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR, + "Failed to refresh existing lock.", + resource->pool); else if (serr) - return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR, - "Failed to refresh existing lock.", - resource->pool); + return dav_svn__sanitize_error(serr, "Failed to refresh existing lock.", + HTTP_INTERNAL_SERVER_ERROR, + resource->info->r); /* Convert the refreshed lock into a dav_lock and return it. */ svn_lock_to_dav_lock(&dlock, slock, FALSE, resource->exists, resource->pool); |