lock.c revision 6f984345bbfa9342dde1f2b7b8c35b7987d078af
af1cb109bce240bcafe3823df022d6088cbfc438Christian Maeder/* ====================================================================
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder * The Apache Software License, Version 1.1
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder * Copyright (c) 2000 The Apache Software Foundation. All rights
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder * Redistribution and use in source and binary forms, with or without
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder * modification, are permitted provided that the following conditions
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder * 1. Redistributions of source code must retain the above copyright
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder * notice, this list of conditions and the following disclaimer.
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder * 2. Redistributions in binary form must reproduce the above copyright
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder * notice, this list of conditions and the following disclaimer in
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder * the documentation and/or other materials provided with the
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder * distribution.
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder * 3. The end-user documentation included with the redistribution,
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder * if any, must include the following acknowledgment:
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder * "This product includes software developed by the
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder * Apache Software Foundation (http://www.apache.org/)."
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder * Alternately, this acknowledgment may appear in the software itself,
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder * if and wherever such third-party acknowledgments normally appear.
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder * 4. The names "Apache" and "Apache Software Foundation" must
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder * not be used to endorse or promote products derived from this
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder * software without prior written permission. For written
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder * permission, please contact apache@apache.org.
af1cb109bce240bcafe3823df022d6088cbfc438Christian Maeder * 5. Products derived from this software may not be called "Apache",
96de7ec4008f75574077816c4c71a22e6afe1e01Christian Maeder * nor may "Apache" appear in their name, without prior written
96de7ec4008f75574077816c4c71a22e6afe1e01Christian Maeder * permission of the Apache Software Foundation.
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
162a689da386fc8ddbbe47bcae83eaca4fc8dbc0Christian Maeder * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
af1cb109bce240bcafe3823df022d6088cbfc438Christian Maeder * SUCH DAMAGE.
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder * ====================================================================
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder * This software consists of voluntary contributions made by many
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder * individuals on behalf of the Apache Software Foundation. For more
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder * information on the Apache Software Foundation, please see
ce59e0cc5c7221245ed323290bfccbda4ee32dd9Christian Maeder** DAV filesystem lock implementation
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder/* ---------------------------------------------------------------
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder** Lock database primitives
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder** LOCK DATABASES
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder** Lockdiscovery information is stored in the single lock database specified
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder** by the DAVLockDB directive. Information about this db is stored in the
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder** global server configuration.
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder** The database is keyed by a key_type unsigned char (DAV_TYPE_INODE or
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder** DAV_TYPE_FNAME) followed by inode and device number if possible,
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder** otherwise full path (in the case of Win32 or lock-null resources).
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder** The value consists of a list of elements.
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder** DIRECT LOCK: [char (DAV_LOCK_DIRECT),
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder** char (dav_lock_scope),
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder** char (dav_lock_type),
af1cb109bce240bcafe3823df022d6088cbfc438Christian Maeder** time_t expires,
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder** apr_uuid_t locktoken,
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder** char[] owner,
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder** char[] auth_user]
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder** INDIRECT LOCK: [char (DAV_LOCK_INDIRECT),
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder** apr_uuid_t locktoken,
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder** time_t expires,
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder** int key_size,
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder** char[] key]
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder** The key is to the collection lock that resulted in this indirect lock
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder/* Stored lock_discovery prefix */
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder/* ack. forward declare. */
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maederstatic dav_error * dav_fs_remove_locknull_member(apr_pool_t *p,
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder** Use the opaquelock scheme for locktokens
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder memcmp(&(plt1)->uuid, &(plt2)->uuid, sizeof((plt1)->uuid))
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder/* #################################################################
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder** ### keep these structures (internal) or move fully to dav_lock?
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder** We need to reliably size the fixed-length portion of
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder** dav_lock_discovery; best to separate it into another
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder** struct for a convenient sizeof, unless we pack lock_discovery.
162a689da386fc8ddbbe47bcae83eaca4fc8dbc0Christian Maeder const char *owner; /* owner field from activelock */
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder const char *auth_user; /* authenticated user who created the lock */
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder/* Indirect locks represent locks inherited from containing collections.
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder * They reference the lock token for the collection the lock is
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder * inherited from. A lock provider may also define a key to the
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder * inherited lock, for fast datbase lookup. The key is opaque outside
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder * the lock provider.
31c6978fd9066c9d2c3c98c950f7abbe89112522Christian Maeder/* ################################################################# */
31c6978fd9066c9d2c3c98c950f7abbe89112522Christian Maeder** Stored direct lock info - full lock_discovery length:
31c6978fd9066c9d2c3c98c950f7abbe89112522Christian Maeder** prefix + Fixed length + lock token + 2 strings + 2 nulls (one for each string)
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder#define dav_size_direct(a) (1 + sizeof(dav_lock_discovery_fixed) \
af1cb109bce240bcafe3823df022d6088cbfc438Christian Maeder + ((a)->auth_user ? strlen((a)->auth_user) : 0) \
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder/* Stored indirect lock info - lock token and dav_datum */
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder#define dav_size_indirect(a) (1 + sizeof(apr_uuid_t) \
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder** The lockdb structure.
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder** The <db> field may be NULL, meaning one of two things:
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder** 1) That we have not actually opened the underlying database (yet). The
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder** <opened> field should be false.
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder** 2) We opened it readonly and it wasn't present.
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder** The delayed opening (determined by <opened>) makes creating a lockdb
31c6978fd9066c9d2c3c98c950f7abbe89112522Christian Maeder** quick, while deferring the underlying I/O until it is actually required.
31c6978fd9066c9d2c3c98c950f7abbe89112522Christian Maeder** We export the notion of a lockdb, but hide the details of it. Most
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder** implementations will use a database of some kind, but it is certainly
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder** possible that alternatives could be used.
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder request_rec *r; /* for accessing the uuid state */
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder const char *lockdb_path; /* where is the lock database? */
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder dav_db *db; /* if non-NULL, the lock database */
31c6978fd9066c9d2c3c98c950f7abbe89112522Christian Maedertypedef struct
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder** The private part of the lock structure.
af1cb109bce240bcafe3823df022d6088cbfc438Christian Maeder dav_datum key; /* key into the lock database */
af1cb109bce240bcafe3823df022d6088cbfc438Christian Maedertypedef struct
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder** This must be forward-declared so the open_lockdb function can use it.
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maederextern const dav_hooks_locks dav_hooks_locks_fs;
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder/* internal function for creating locks */
162a689da386fc8ddbbe47bcae83eaca4fc8dbc0Christian Maederstatic dav_lock *dav_fs_alloc_lock(dav_lockdb *lockdb, dav_datum key,
bd8ff5b5f66be563e5be9d3a0c069e32d06f331cChristian Maeder comb = apr_pcalloc(lockdb->info->pool, sizeof(*comb));
ce59e0cc5c7221245ed323290bfccbda4ee32dd9Christian Maeder** dav_fs_parse_locktoken
ce59e0cc5c7221245ed323290bfccbda4ee32dd9Christian Maeder** Parse an opaquelocktoken URI into a locktoken.
ce59e0cc5c7221245ed323290bfccbda4ee32dd9Christian Maeder if (ap_strstr_c(char_token, "opaquelocktoken:") != char_token) {
af1cb109bce240bcafe3823df022d6088cbfc438Christian Maeder HTTP_BAD_REQUEST, DAV_ERR_LOCK_UNK_STATE_TOKEN,
af1cb109bce240bcafe3823df022d6088cbfc438Christian Maeder "The lock token uses an unknown State-token "
af1cb109bce240bcafe3823df022d6088cbfc438Christian Maeder "format and could not be parsed.");
af1cb109bce240bcafe3823df022d6088cbfc438Christian Maeder locktoken = apr_pcalloc(p, sizeof(*locktoken));
af1cb109bce240bcafe3823df022d6088cbfc438Christian Maeder if (apr_parse_uuid(&locktoken->uuid, char_token)) {
af1cb109bce240bcafe3823df022d6088cbfc438Christian Maeder return dav_new_error(p, HTTP_BAD_REQUEST, DAV_ERR_LOCK_PARSE_TOKEN,
af1cb109bce240bcafe3823df022d6088cbfc438Christian Maeder "The opaquelocktoken has an incorrect format "
af1cb109bce240bcafe3823df022d6088cbfc438Christian Maeder "and could not be parsed.");
af1cb109bce240bcafe3823df022d6088cbfc438Christian Maeder** dav_fs_format_locktoken
af1cb109bce240bcafe3823df022d6088cbfc438Christian Maeder** Generate the URI for a locktoken
af1cb109bce240bcafe3823df022d6088cbfc438Christian Maederstatic const char *dav_fs_format_locktoken(
af1cb109bce240bcafe3823df022d6088cbfc438Christian Maeder return apr_pstrcat(p, "opaquelocktoken:", buf, NULL);
af1cb109bce240bcafe3823df022d6088cbfc438Christian Maeder** dav_fs_compare_locktoken
af1cb109bce240bcafe3823df022d6088cbfc438Christian Maeder** Determine whether two locktokens are the same
return NULL;
err);
return NULL;
if (force) {
return NULL;
return key;
#ifndef WIN32
return key;
char *ptr;
#if DAV_DEBUG
return err;
return NULL;
while(dp) {
while(ip) {
while(dp) {
while(ip) {
err);
return NULL;
int add_method,
return err;
return NULL;
return err;
return NULL;
case DAV_LOCK_DIRECT:
++offset;
++offset;
return err;
case DAV_LOCK_INDIRECT:
--offset;
return dav_new_error(p,
apr_psprintf(p,
return NULL;
return err;
return NULL;
return supported;
p) != APR_SUCCESS) {
return NULL;
apr_psprintf(p,
goto loaderror;
apr_psprintf(p,
goto loaderror;
return err;
const char *pathname;
return NULL;
NULL);
apr_psprintf(p,
return NULL;
apr_psprintf(p,
pathname));
apr_psprintf(p,
return err;
const char *filename,
char *scan;
const char *scanend;
int dirty = 0;
return err;
if (dirty) {
return err;
return NULL;
/* Note: used by dav_fs_repos.c */
const char *dirpath;
const char *dirpath;
const char *fname;
return NULL;
return err;
#ifndef WIN32
return err;
return err;
return err;
return NULL;
key,
NULL);
return NULL;
int calltype,
#if DAV_DEBUG
return err;
return err;
return NULL;
int partial_ok,
return err;
return NULL;
if (partial_ok) {
return err;
return NULL;
return NULL;
int *locks_present)
*locks_present = 0;
return err;
return NULL;
return NULL;
int make_indirect,
return err;
if (make_indirect) {
return err;
return err;
return NULL;
return err;
if (dprev)
if (iprev)
return err;
return err;
return NULL;
int dirty = 0;
return dirty;
int dirty = 0;
return err;
if (dirty
return err;
return err;
return err;
return NULL;