summaryrefslogtreecommitdiff
path: root/subversion/mod_dav_svn/lock.c
diff options
context:
space:
mode:
Diffstat (limited to 'subversion/mod_dav_svn/lock.c')
-rw-r--r--subversion/mod_dav_svn/lock.c69
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);