/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
** DAV repository-independent lock functions
*/

#include "apr.h"
#include "apr_strings.h"

#include "mod_dav.h"
#include "http_log.h"
#include "http_config.h"
#include "http_protocol.h"
#include "http_core.h"

APLOG_USE_MODULE(dav);

/* ---------------------------------------------------------------
**
** Property-related lock functions
**
*/

/*
** dav_lock_get_activelock:  Returns a <lockdiscovery> containing
**    an activelock element for every item in the lock_discovery tree
*/
DAV_DECLARE(const char *) dav_lock_get_activelock(request_rec *r,
                                                  dav_lock *lock,
                                                  dav_buffer *pbuf)
{
    dav_lock *lock_scan;
    const dav_hooks_locks *hooks = DAV_GET_HOOKS_LOCKS(r);
    int count = 0;
    dav_buffer work_buf = { 0 };
    apr_pool_t *p = r->pool;

    /* If no locks or no lock provider, there are no locks */
    if (lock == NULL || hooks == NULL) {
        /*
        ** Since resourcediscovery is defined with (activelock)*,
        ** <D:activelock/> shouldn't be necessary for an empty lock.
        */
        return "";
    }

    /*
    ** Note: it could be interesting to sum the lengths of the owners
    **       and locktokens during this loop. However, the buffer
    **       mechanism provides some rough padding so that we don't
    **       really need to have an exact size. Further, constructing
    **       locktoken strings could be relatively expensive.
    */
    for (lock_scan = lock; lock_scan != NULL; lock_scan = lock_scan->next)
        count++;

    /* if a buffer was not provided, then use an internal buffer */
    if (pbuf == NULL)
        pbuf = &work_buf;

    /* reset the length before we start appending stuff */
    pbuf->cur_len = 0;

    /* prep the buffer with a "good" size */
    dav_check_bufsize(p, pbuf, count * 300);

    for (; lock != NULL; lock = lock->next) {
        char tmp[100];

#if DAV_DEBUG
        if (lock->rectype == DAV_LOCKREC_INDIRECT_PARTIAL) {
            /* ### crap. design error */
            dav_buffer_append(p, pbuf,
                              "DESIGN ERROR: attempted to product an "
                              "activelock element from a partial, indirect "
                              "lock record. Creating an XML parsing error "
                              "to ease detection of this situation: <");
        }
#endif

        dav_buffer_append(p, pbuf, "<D:activelock>" DEBUG_CR "<D:locktype>");
        switch (lock->type) {
        case DAV_LOCKTYPE_WRITE:
            dav_buffer_append(p, pbuf, "<D:write/>");
            break;
        default:
            /* ### internal error. log something? */
            break;
        }
        dav_buffer_append(p, pbuf, "</D:locktype>" DEBUG_CR "<D:lockscope>");
        switch (lock->scope) {
        case DAV_LOCKSCOPE_EXCLUSIVE:
            dav_buffer_append(p, pbuf, "<D:exclusive/>");
            break;
        case DAV_LOCKSCOPE_SHARED:
            dav_buffer_append(p, pbuf, "<D:shared/>");
            break;
        default:
            /* ### internal error. log something? */
            break;
        }
        dav_buffer_append(p, pbuf, "</D:lockscope>" DEBUG_CR);
        apr_snprintf(tmp, sizeof(tmp), "<D:depth>%s</D:depth>" DEBUG_CR,
                     lock->depth == DAV_INFINITY ? "infinity" : "0");
        dav_buffer_append(p, pbuf, tmp);

        if (lock->owner) {
            /*
            ** This contains a complete, self-contained <DAV:owner> element,
            ** with namespace declarations and xml:lang handling. Just drop
            ** it in.
            */
            dav_buffer_append(p, pbuf, lock->owner);
        }

        dav_buffer_append(p, pbuf, "<D:timeout>");
        if (lock->timeout == DAV_TIMEOUT_INFINITE) {
            dav_buffer_append(p, pbuf, "Infinite");
        }
        else {
            time_t now = time(NULL);
            
            /*
            ** Check if the timeout is not, for any reason, already elapsed.
            ** (e.g., because of a large collection, or disk under heavy load...)
             */
            if (now >= lock->timeout) {
                dav_buffer_append(p, pbuf, "Second-0");
            }
            else {
                apr_snprintf(tmp, sizeof(tmp), "Second-%lu", (long unsigned int)(lock->timeout - now));
                dav_buffer_append(p, pbuf, tmp);
            }
        }

        dav_buffer_append(p, pbuf,
                          "</D:timeout>" DEBUG_CR
                          "<D:locktoken>" DEBUG_CR
                          "<D:href>");
        dav_buffer_append(p, pbuf,
                          (*hooks->format_locktoken)(p, lock->locktoken));
        dav_buffer_append(p, pbuf,
                          "</D:href>" DEBUG_CR
                          "</D:locktoken>" DEBUG_CR
                          "</D:activelock>" DEBUG_CR);
    }

    return pbuf->buf;
}

/*
** dav_lock_parse_lockinfo:  Validates the given xml_doc to contain a
**    lockinfo XML element, then populates a dav_lock structure
**    with its contents.
*/
DAV_DECLARE(dav_error *) dav_lock_parse_lockinfo(request_rec *r,
                                                 const dav_resource *resource,
                                                 dav_lockdb *lockdb,
                                                 const apr_xml_doc *doc,
                                                 dav_lock **lock_request)
{
    apr_pool_t *p = r->pool;
    dav_error *err;
    apr_xml_elem *child;
    dav_lock *lock;

    if (!dav_validate_root(doc, "lockinfo")) {
        return dav_new_error(p, HTTP_BAD_REQUEST, 0, 0,
                             "The request body contains an unexpected "
                             "XML root element.");
    }

    if ((err = (*lockdb->hooks->create_lock)(lockdb, resource,
                                             &lock)) != NULL) {
        return dav_push_error(p, err->status, 0,
                              "Could not parse the lockinfo due to an "
                              "internal problem creating a lock structure.",
                              err);
    }

    lock->depth = dav_get_depth(r, DAV_INFINITY);
    if (lock->depth == -1) {
        return dav_new_error(p, HTTP_BAD_REQUEST, 0, 0,
                             "An invalid Depth header was specified.");
    }
    lock->timeout = dav_get_timeout(r);

    /* Parse elements in the XML body */
    for (child = doc->root->first_child; child; child = child->next) {
        if (strcmp(child->name, "locktype") == 0
            && child->first_child
            && lock->type == DAV_LOCKTYPE_UNKNOWN) {
            if (strcmp(child->first_child->name, "write") == 0) {
                lock->type = DAV_LOCKTYPE_WRITE;
                continue;
            }
        }
        if (strcmp(child->name, "lockscope") == 0
            && child->first_child
            && lock->scope == DAV_LOCKSCOPE_UNKNOWN) {
            if (strcmp(child->first_child->name, "exclusive") == 0)
                lock->scope = DAV_LOCKSCOPE_EXCLUSIVE;
            else if (strcmp(child->first_child->name, "shared") == 0)
                lock->scope = DAV_LOCKSCOPE_SHARED;
            if (lock->scope != DAV_LOCKSCOPE_UNKNOWN)
                continue;
        }

        if (strcmp(child->name, "owner") == 0 && lock->owner == NULL) {
            const char *text;

            /* quote all the values in the <DAV:owner> element */
            apr_xml_quote_elem(p, child);

            /*
            ** Store a full <DAV:owner> element with namespace definitions
            ** and an xml:lang definition, if applicable.
            */
            apr_xml_to_text(p, child, APR_XML_X2T_FULL_NS_LANG, doc->namespaces,
                            NULL, &text, NULL);
            lock->owner = text;

            continue;
        }

        return dav_new_error(p, HTTP_PRECONDITION_FAILED, 0, 0,
                             apr_psprintf(p,
                                         "The server cannot satisfy the "
                                         "LOCK request due to an unknown XML "
                                         "element (\"%s\") within the "
                                         "DAV:lockinfo element.",
                                         child->name));
    }

    *lock_request = lock;
    return NULL;
}

/* ---------------------------------------------------------------
**
** General lock functions
**
*/

/* dav_lock_walker:  Walker callback function to record indirect locks */
static dav_error * dav_lock_walker(dav_walk_resource *wres, int calltype)
{
    dav_walker_ctx *ctx = wres->walk_ctx;
    dav_error *err;

    /* We don't want to set indirects on the target */
    if ((*wres->resource->hooks->is_same_resource)(wres->resource,
                                                   ctx->w.root))
        return NULL;

    if ((err = (*ctx->w.lockdb->hooks->append_locks)(ctx->w.lockdb,
                                                     wres->resource, 1,
                                                     ctx->lock)) != NULL) {
        if (ap_is_HTTP_SERVER_ERROR(err->status)) {
            /* ### add a higher-level description? */
            return err;
        }

        /* add to the multistatus response */
        dav_add_response(wres, err->status, NULL);

        /*
        ** ### actually, this is probably wrong: we want to fail the whole
        ** ### LOCK process if something goes bad. maybe the caller should
        ** ### do a dav_unlock() (e.g. a rollback) if any errors occurred.
        */
    }

    return NULL;
}

/*
** dav_add_lock:  Add a direct lock for resource, and indirect locks for
**    all children, bounded by depth.
**    ### assume request only contains one lock
*/
DAV_DECLARE(dav_error *) dav_add_lock(request_rec *r,
                                      const dav_resource *resource,
                                      dav_lockdb *lockdb, dav_lock *lock,
                                      dav_response **response)
{
    dav_error *err;
    int depth = lock->depth;

    *response = NULL;

    /* Requested lock can be:
     *   Depth: 0   for null resource, existing resource, or existing collection
     *   Depth: Inf for existing collection
     */

    /*
    ** 2518 9.2 says to ignore depth if target is not a collection (it has
    **   no internal children); pretend the client gave the correct depth.
    */
    if (!resource->collection) {
        depth = 0;
    }

    /* In all cases, first add direct entry in lockdb */

    /*
    ** Append the new (direct) lock to the resource's existing locks.
    **
    ** Note: this also handles locknull resources
    */
    if ((err = (*lockdb->hooks->append_locks)(lockdb, resource, 0,
                                              lock)) != NULL) {
        /* ### maybe add a higher-level description */
        return err;
    }

    if (depth > 0) {
        /* Walk existing collection and set indirect locks */
        dav_walker_ctx ctx = { { 0 } };
        dav_response *multi_status;

        ctx.w.walk_type = DAV_WALKTYPE_NORMAL | DAV_WALKTYPE_AUTH;
        ctx.w.func = dav_lock_walker;
        ctx.w.walk_ctx = &ctx;
        ctx.w.pool = r->pool;
        ctx.w.root = resource;
        ctx.w.lockdb = lockdb;

        ctx.r = r;
        ctx.lock = lock;

        err = (*resource->hooks->walk)(&ctx.w, DAV_INFINITY, &multi_status);
        if (err != NULL) {
            /* implies a 5xx status code occurred. screw the multistatus */
            return err;
        }

        if (multi_status != NULL) {
            /* manufacture a 207 error for the multistatus response */
            *response = multi_status;
            return dav_new_error(r->pool, HTTP_MULTI_STATUS, 0, 0,
                                 "Error(s) occurred on resources during the "
                                 "addition of a depth lock.");
        }
    }

    return NULL;
}

/*
** dav_lock_query:  Opens the lock database. Returns a linked list of
**    dav_lock structures for all direct locks on path.
*/
DAV_DECLARE(dav_error*) dav_lock_query(dav_lockdb *lockdb,
                                       const dav_resource *resource,
                                       dav_lock **locks)
{
    /* If no lock database, return empty result */
    if (lockdb == NULL) {
        *locks = NULL;
        return NULL;
    }

    /* ### insert a higher-level description? */
    return (*lockdb->hooks->get_locks)(lockdb, resource,
                                       DAV_GETLOCKS_RESOLVED,
                                       locks);
}

/* dav_unlock_walker:  Walker callback function to remove indirect locks */
static dav_error * dav_unlock_walker(dav_walk_resource *wres, int calltype)
{
    dav_walker_ctx *ctx = wres->walk_ctx;
    dav_error *err;

    /* Before removing the lock, do any auto-checkin required */
    if (wres->resource->working) {
        /* ### get rid of this typecast */
        if ((err = dav_auto_checkin(ctx->r, (dav_resource *) wres->resource,
                                    0 /*undo*/, 1 /*unlock*/, NULL))
            != NULL) {
            return err;
        }
    }

    if ((err = (*ctx->w.lockdb->hooks->remove_lock)(ctx->w.lockdb,
                                                    wres->resource,
                                                    ctx->locktoken)) != NULL) {
        /* ### should we stop or return a multistatus? looks like STOP */
        /* ### add a higher-level description? */
        return err;
    }

    return NULL;
}

/*
** dav_get_direct_resource:
**
** Find a lock on the specified resource, then return the resource the
** lock was applied to (in other words, given a (possibly) indirect lock,
** return the direct lock's corresponding resource).
**
** If the lock is an indirect lock, this usually means traversing up the
** namespace [repository] hierarchy. Note that some lock providers may be
** able to return this information with a traversal.
*/
static dav_error * dav_get_direct_resource(apr_pool_t *p,
                                           dav_lockdb *lockdb,
                                           const dav_locktoken *locktoken,
                                           const dav_resource *resource,
                                           const dav_resource **direct_resource)
{
    if (lockdb->hooks->lookup_resource != NULL) {
        return (*lockdb->hooks->lookup_resource)(lockdb, locktoken,
                                                 resource, direct_resource);
    }

    *direct_resource = NULL;

    /* Find the top of this lock-
     * If r->filename's direct   locks include locktoken, use r->filename.
     * If r->filename's indirect locks include locktoken, retry r->filename/..
     * Else fail.
     */
    while (resource != NULL) {
        dav_error *err;
        dav_lock *lock;
        dav_resource *parent;

        /*
        ** Find the lock specified by <locktoken> on <resource>. If it is
        ** an indirect lock, then partial results are okay. We're just
        ** trying to find the thing and know whether it is a direct or
        ** an indirect lock.
        */
        if ((err = (*lockdb->hooks->find_lock)(lockdb, resource, locktoken,
                                               1, &lock)) != NULL) {
            /* ### add a higher-level desc? */
            return err;
        }

        /* not found! that's an error. */
        if (lock == NULL) {
            return dav_new_error(p, HTTP_BAD_REQUEST, 0, 0,
                                 "The specified locktoken does not correspond "
                                 "to an existing lock on this resource.");
        }

        if (lock->rectype == DAV_LOCKREC_DIRECT) {
            /* we found the direct lock. return this resource. */

            *direct_resource = resource;
            return NULL;
        }

        /* the lock was indirect. move up a level in the URL namespace */
        if ((err = (*resource->hooks->get_parent_resource)(resource,
                                                           &parent)) != NULL) {
            /* ### add a higher-level desc? */
            return err;
        }
        resource = parent;
    }

    return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0, 0,
                         "The lock database is corrupt. A direct lock could "
                         "not be found for the corresponding indirect lock "
                         "on this resource.");
}

/*
** dav_unlock:  Removes all direct and indirect locks for r->filename,
**    with given locktoken.  If locktoken == null_locktoken, all locks
**    are removed.  If r->filename represents an indirect lock,
**    we must unlock the appropriate direct lock.
**    Returns OK or appropriate HTTP_* response and logs any errors.
**
** ### We've already crawled the tree to ensure everything was locked
**     by us; there should be no need to incorporate a rollback.
*/
DAV_DECLARE(int) dav_unlock(request_rec *r, const dav_resource *resource,
                            const dav_locktoken *locktoken)
{
    int result;
    dav_lockdb *lockdb;
    const dav_resource *lock_resource = resource;
    const dav_hooks_locks *hooks = DAV_GET_HOOKS_LOCKS(r);
    const dav_hooks_repository *repos_hooks = resource->hooks;
    dav_walker_ctx ctx = { { 0 } };
    dav_response *multi_status;
    dav_error *err;

    /* If no locks provider, then there is nothing to unlock. */
    if (hooks == NULL) {
        return OK;
    }

    /* 2518 requires the entire lock to be removed if resource/locktoken
     * point to an indirect lock.  We need resource of the _direct_
     * lock in order to walk down the tree and remove the locks.  So,
     * If locktoken != null_locktoken,
     *    Walk up the resource hierarchy until we see a direct lock.
     *    Or, we could get the direct lock's db/key, pick out the URL
     *    and do a subrequest.  I think walking up is faster and will work
     *    all the time.
     * Else
     *    Just start removing all locks at and below resource.
     */

    if ((err = (*hooks->open_lockdb)(r, 0, 1, &lockdb)) != NULL) {
        /* ### return err! maybe add a higher-level desc */
        /* ### map result to something nice; log an error */
        return HTTP_INTERNAL_SERVER_ERROR;
    }

    if (locktoken != NULL
        && (err = dav_get_direct_resource(r->pool, lockdb,
                                          locktoken, resource,
                                          &lock_resource)) != NULL) {
        /* ### add a higher-level desc? */
        /* ### should return err! */
        return err->status;
    }

    /* At this point, lock_resource/locktoken refers to a direct lock (key), ie
     * the root of a depth > 0 lock, or locktoken is null.
     */
    ctx.w.walk_type = DAV_WALKTYPE_NORMAL | DAV_WALKTYPE_LOCKNULL;
    ctx.w.func = dav_unlock_walker;
    ctx.w.walk_ctx = &ctx;
    ctx.w.pool = r->pool;
    ctx.w.root = lock_resource;
    ctx.w.lockdb = lockdb;

    ctx.r = r;
    ctx.locktoken = locktoken;

    err = (*repos_hooks->walk)(&ctx.w, DAV_INFINITY, &multi_status);

    /* ### fix this! */
    /* ### do something with multi_status */
    result = err == NULL ? OK : err->status;

    (*hooks->close_lockdb)(lockdb);

    return result;
}

/* dav_inherit_walker:  Walker callback function to inherit locks */
static dav_error * dav_inherit_walker(dav_walk_resource *wres, int calltype)
{
    dav_walker_ctx *ctx = wres->walk_ctx;

    if (ctx->skip_root
        && (*wres->resource->hooks->is_same_resource)(wres->resource,
                                                      ctx->w.root)) {
        return NULL;
    }

    /* ### maybe add a higher-level desc */
    return (*ctx->w.lockdb->hooks->append_locks)(ctx->w.lockdb,
                                                 wres->resource, 1,
                                                 ctx->lock);
}

/*
** dav_inherit_locks:  When a resource or collection is added to a collection,
**    locks on the collection should be inherited to the resource/collection.
**    (MOVE, MKCOL, etc) Here we propagate any direct or indirect locks from
**    parent of resource to resource and below.
*/
static dav_error * dav_inherit_locks(request_rec *r, dav_lockdb *lockdb,
                                     const dav_resource *resource,
                                     int use_parent)
{
    dav_error *err;
    const dav_resource *which_resource;
    dav_lock *locks;
    dav_lock *scan;
    dav_lock *prev;
    dav_walker_ctx ctx = { { 0 } };
    const dav_hooks_repository *repos_hooks = resource->hooks;
    dav_response *multi_status;

    if (use_parent) {
        dav_resource *parent;
        if ((err = (*repos_hooks->get_parent_resource)(resource,
                                                       &parent)) != NULL) {
            /* ### add a higher-level desc? */
            return err;
        }
        if (parent == NULL) {
            /* ### map result to something nice; log an error */
            return dav_new_error(r->pool, HTTP_INTERNAL_SERVER_ERROR, 0, 0,
                                 "Could not fetch parent resource. Unable to "
                                 "inherit locks from the parent and apply "
                                 "them to this resource.");
        }
        which_resource = parent;
    }
    else {
        which_resource = resource;
    }

    if ((err = (*lockdb->hooks->get_locks)(lockdb, which_resource,
                                           DAV_GETLOCKS_PARTIAL,
                                           &locks)) != NULL) {
        /* ### maybe add a higher-level desc */
        return err;
    }

    if (locks == NULL) {
        /* No locks to propagate, just return */
        return NULL;
    }

    /*
    ** (1) Copy all indirect locks from our parent;
    ** (2) Create indirect locks for the depth infinity, direct locks
    **     in our parent.
    **
    ** The append_locks call in the walker callback will do the indirect
    ** conversion, but we need to remove any direct locks that are NOT
    ** depth "infinity".
    */
    for (scan = locks, prev = NULL;
         scan != NULL;
         prev = scan, scan = scan->next) {

        if (scan->rectype == DAV_LOCKREC_DIRECT
            && scan->depth != DAV_INFINITY) {

            if (prev == NULL)
                locks = scan->next;
            else
                prev->next = scan->next;
        }
    }

    /* <locks> has all our new locks.  Walk down and propagate them. */

    ctx.w.walk_type = DAV_WALKTYPE_NORMAL | DAV_WALKTYPE_LOCKNULL;
    ctx.w.func = dav_inherit_walker;
    ctx.w.walk_ctx = &ctx;
    ctx.w.pool = r->pool;
    ctx.w.root = resource;
    ctx.w.lockdb = lockdb;

    ctx.r = r;
    ctx.lock = locks;
    ctx.skip_root = !use_parent;

    /* ### do something with multi_status */
    return (*repos_hooks->walk)(&ctx.w, DAV_INFINITY, &multi_status);
}

/* ---------------------------------------------------------------
**
** Functions dealing with lock-null resources
**
*/

/*
** dav_get_resource_state:  Returns the state of the resource
**    r->filename:  DAV_RESOURCE_NULL, DAV_RESOURCE_LOCK_NULL,
**    or DAV_RESOURCE_EXIST.
**
**    Returns DAV_RESOURCE_ERROR if an error occurs.
*/
DAV_DECLARE(int) dav_get_resource_state(request_rec *r,
                                        const dav_resource *resource)
{
    const dav_hooks_locks *hooks = DAV_GET_HOOKS_LOCKS(r);

    if (resource->exists)
        return DAV_RESOURCE_EXISTS;

    if (hooks != NULL) {
        dav_error *err;
        dav_lockdb *lockdb;
        int locks_present;

        /*
        ** A locknull resource has the form:
        **
        **   known-dir "/" locknull-file
        **
        ** It would be nice to look into <resource> to verify this form,
        ** but it does not have enough information for us. Instead, we
        ** can look at the path_info. If the form does not match, then
        ** there is no way we could have a locknull resource -- it must
        ** be a plain, null resource.
        **
        ** Apache sets r->filename to known-dir/unknown-file and r->path_info
        ** to "" for the "proper" case. If anything is in path_info, then
        ** it can't be a locknull resource.
        **
        ** ### I bet this path_info hack doesn't work for repositories.
        ** ### Need input from repository implementors! What kind of
        ** ### restructure do we need? New provider APIs?
        */
        if (r->path_info != NULL && *r->path_info != '\0') {
            return DAV_RESOURCE_NULL;
        }

        if ((err = (*hooks->open_lockdb)(r, 1, 1, &lockdb)) == NULL) {
            /* note that we might see some expired locks... *shrug* */
            err = (*hooks->has_locks)(lockdb, resource, &locks_present);
            (*hooks->close_lockdb)(lockdb);
        }

        if (err != NULL) {
            /* ### don't log an error. return err. add higher-level desc. */

            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00623)
                          "Failed to query lock-null status for %s",
                          r->filename);

            return DAV_RESOURCE_ERROR;
        }

        if (locks_present)
            return DAV_RESOURCE_LOCK_NULL;
    }

    return DAV_RESOURCE_NULL;
}

DAV_DECLARE(dav_error *) dav_notify_created(request_rec *r,
                                            dav_lockdb *lockdb,
                                            const dav_resource *resource,
                                            int resource_state,
                                            int depth)
{
    dav_error *err;

    if (resource_state == DAV_RESOURCE_LOCK_NULL) {

        /*
        ** The resource is no longer a locknull resource. This will remove
        ** the special marker.
        **
        ** Note that a locknull resource has already inherited all of the
        ** locks from the parent. We do not need to call dav_inherit_locks.
        **
        ** NOTE: some lock providers record locks for locknull resources using
        **       a different key than for regular resources. this will shift
        **       the lock information between the two key types.
        */
        (void)(*lockdb->hooks->remove_locknull_state)(lockdb, resource);

        /*
        ** There are resources under this one, which are new. We must
        ** propagate the locks down to the new resources.
        */
        if (depth > 0 &&
            (err = dav_inherit_locks(r, lockdb, resource, 0)) != NULL) {
            /* ### add a higher level desc? */
            return err;
        }
    }
    else if (resource_state == DAV_RESOURCE_NULL) {

        /* ### should pass depth to dav_inherit_locks so that it can
        ** ### optimize for the depth==0 case.
        */

        /* this resource should inherit locks from its parent */
        if ((err = dav_inherit_locks(r, lockdb, resource, 1)) != NULL) {

            err = dav_push_error(r->pool, err->status, 0,
                                 "The resource was created successfully, but "
                                 "there was a problem inheriting locks from "
                                 "the parent resource.",
                                 err);
            return err;
        }
    }
    /* else the resource already exists and its locks are correct. */

    return NULL;
}
