Subject: locking GULP 2

From: [email-masked]
Date: Wed, 26 Jan 2000 17:49:04 -0500

Geoff,
Just a couple of comments, I'm trying to catch up from a lot of travel.
- a lock must be an 8 tuple and include the principal (authentication id)
who owns the lock.
- under "A resource can be locked by multiple locks concurrently", the
first sentence should read A resource..., not a lock...
- under "One or more resources may be locked with a lock request", last
paragraph: unfortunately the owner element of a lock is not the principal
owning the lock but rather some arbitrary string describing the owner of
the lock like a phone number or email address, etc. That's why we need
another field for the principal. Otherwise client applications must persist
their lock tokens somewhere else as there's no way to retrieve them from
the server for a given user.
- say you have a lock on a resource which translates to a lock on its
segment binding in its parent collection (the one used to request the
lock), and the resource itself. Now you move the resource to some other
collection. This removes the lock from the binding in the collection, but
not the lock on the resource itself? If so, could one expect that a new
lock would be added to destination binding so that the overall state of the
system is the same? The user started out with a protected resource and URL.
After the move, one would expect the same level of protection?

"Geoffrey M. Clemm" <[email-masked]>@w3.org on 01/14/2000
01:11:54 AM

Sent by:  [email-masked]

To:   [email-masked]
cc:

Subject:  GULP, version 2

Here is a second version of the GULP.  I've updated the descriptive
text based on the feedback from Jason, Jim, and Eric (not that I've
successfully addressed their issues, but it was based on it :-).
Jason: I'm now using "target" instead of "name" ... let me know if
you think that works better.

The only semantic change has been the deletion of Depth:N behavior,
for N other than 0 and infinity (this brings it more in line with 2518).

I need some more examples, and I still need to address the use cases
raised by Eric and Jason ...  I believe they are handled properly by
the proposal, but I probably should get some sleep first before
working them through (:-).

Cheers,
Geoff

**************************

GULP: Part I

- A URL is a string that can identify a resource.

- A collection is a resource that contains a set of named members.

- A lock is 7-tuple, consisting of a target, token, type, scope,
depth, timeout, and owner.

- Locking a resource means to add a lock to the state of that
resource.

- Unlocking a resource means to remove a lock from the state of that
resource.

- A lock will cause certain requests to fail with a 423 (Locked)
status code, where that request would have succeeded if the lock had
not been present.

- A resource can be locked by multiple locks concurrently.

- One or more resources can be locked with a LOCK request.

- Locking a collection can lock one or more members of that
collection.

- Adding a resource to a locked collectin can lock that resource.

- One or more resources can be unlocked with an UNLOCK request.

- Unlocking a collection can unlock one or more members of that
collection.

- Removing a resource from a locked collection can unlock that resource.

- The depth of a lock can be a 0 or infinity.  If a collection has a
depth infinity lock, all members of that collection are also locked.

- If a member is added to a depth:infinity locked collection, that
member is locked by that depth:infinity lock.

- A lock protects which resource is identified by that lock.

- If a resource has an exclusive lock, that resource cannot be locked
with another lock with the same type and target but a different token.

- If a resource has a write lock with target ".", the body and
properties of that resource are protected from unauthorized
modification.

**************************

GULP: Part II

- A URL is a string that can identify a resource.

A server initially defines what resource (if any) is identified by a
URL.  Most URL's do not identify a resource, but a client can cause
a URL to identify a resource, and later change which resource is
identified by that URL.

Examples of methods that can cause a URL to identify a resource (or
change the resource identified by a URL) are PUT, MKRESOURCE, MKCOL,
BIND, MOVE, and COPY.  Examples of methods that can cause a URL to no
longer identify a resource are DELETE and MOVE.

- A lock is 7-tuple, consisting of a target, token, type, scope, depth,
timeout, and owner.

The "target" is an extension to locks as defined in rfc2518.  This new
field is defined to distinguish the implicit locks on the state of a
collection implied by the locking semantics of rfc2518, from the
explicit locks that are defined by rfc2518.  The explicit locks in
rfc2518 correspond to locks with target "." in this proposal.

Since all locks with the same token will share the same type, scope,
depth, timeout, and owner, a lock will be represented in this proposal
as a string of the form "[target, token]".

For example, ["x/.", "K"] defines a lock with target "x/." and token "K".

- A collection is a resource that contains a set of named members.

A collection contains a set of bindings, where a binding is a mapping
from a URL segment to a resource.  If a URL identifies a collection,
that URL extended by the URL segment will identify the bound resource.

For example, If "/path" identifies a collection C, and C contains a
binding that binds the segment "x" to resource R, then the URL
"/path/x" identifies resource R.

- Locking a resource means to add a lock to the state of that
resource.

The lock is added to the DAV:lockdiscovery property of the resource.

- Unlocking a resource means to remove a lock from the state of that
resource.

The lock is deleted from the DAV:lockdiscovery property of the
resource.

- A lock will cause certain requests to fail with a 423 (Locked)
status code, where that request would have succeeded if the lock had
not been present.

Whether a particular request will fail can depends on the
target, token, type, scope, and owner of the lock.

- A resource can be locked by multiple locks concurrently.

A lock can be locked by multiple locks with different values or
multiple identical locks.  Some lock combinations will be disallowed
based on information such as the the scope of the lock.

- One or more resources can be locked with a LOCK request.

When a LOCK request succeeds, a lock is added to the resource
identified by shortest sequence of initial segments of the request URL
that identifies a WebDAV resource.

The lock target is the relative URL formed by using standard URL
transformations to remove all segments of the request-URL named "." or
"..", then removing the prefix that identifies the locked resource,
and then appending a segment named ".".

For example, if "LOCK /seg1/seg2/seg3/.../segN" succeeds, and if
/seg1 does not identify a WebDAV resource but /seg1/seg2 does,
then a lock with target "seg3/.../segN/." is added to the resource
identified by "/seg1/seg2".

The type and scope, and owner of the lock is specified in the LOCK
request body.  The depth and timeout of the lock is specified in the
LOCK request headers.  The token of the lock is a unique string
allocated for that LOCK request by the server.

The principal that issued the LOCK request is called the "owner" of
the lock.

- Locking a collection can lock one or more members of that collection.

If a collection C has a binding from "segX" to resource R, and a
request adds a ["segX/pathZ", "K"] lock to C, then the request adds a
["pathZ", "K"] lock to R.

- Adding a resource to a locked collectin can lock that resource.

If a collection C has a ["segX/pathZ", "K"] lock, and a request adds a
binding in C from "segX" to resource R, then the request adds a
["pathZ", "K"] lock to R. If the attempt to add this lock to R fails,
the request MUST fail.

- One or more resources can be unlocked with an UNLOCK request.

When a request of the form "UNLOCK /pathX; Lock-Token K" succeeds,
then all locks with token "K" are removed.

- Unlocking a collection can unlock one or more members of that
collection.

If a collection C has a binding from "segX" to resource R, and a
request removes a ["segX/pathZ", "K"] lock from C, then the request
removes a ["pathZ", "K"] lock from R.

- Removing a resource from a locked collection can unlock that resource.

If a collection has a ["segX/pathZ", "K"] lock, and a request removes
a binding in C from "segX" to resource R, then a ["pathZ", "K"] lock
is removed from R.

- The depth of a lock can be a 0 or infinity.  If a collection has a
depth infinity lock, all members of that collection are also locked.

If a collection C has a binding to resource R, and a request adds a
Depth:infinity [".", "K"] lock to C, and this is the first [".", "K"]
lock on C, then the request adds a [".", "K"] lock to R.  Conversely,
if a collection C has a binding to resource R, and a request removes
the last Depth:infinity [".", "K"] lock from C, then the request
removes a [".", "K"] lock from R.

Note that multiple Depth:infinity locks with target "." and with the
same token can be placed on the same resource due to multiple bindings
to that resource in a Depth:infinity locked collection.  Only the
first such lock on a particular collection adds locks to the members
of that collection to avoid generating an infinite number of locks for
cyclic bindings.

- If a member is added to a depth:infinity locked collection, that
member is locked by that depth:infinity lock.

If a collection C has a Depth:infinity [".", "K"] lock, and a request
adds a binding in C to resource R, then the request adds a [".","K"]
lock to R. If the attempt to add this lock to R fails, the request
MUST fail.  Conversely, if a collection has a Depth:infinity [".",
"K"] lock, and a request removes a binding in C to resource R, then a
[".", "K"] lock removed from R.

- A lock protects which resource is identified by that lock.

More precisely, if a collection has a ["X/....", "K"] lock, a request
cannot delete the member named X from that collection unless the
principal of the request owns all locks with target "X/..." and the
tokens of all those locks are specified in an IF header.

- If a resource has an exclusive lock, that resource cannot be locked
with another locks with the same type and target but a different
token.

If a request attempts to add a type T ["pathZ", "K"] lock to resource
R, and R already has an exclusive lock with target "pathZ" and type T
but with a different token, the request MUST fail. Similarly, if a
request attempts to add an exclusive type T ["pathZ", "K"] lock to
resource R, and R already has a lock with target "pathZ" and type T
but with a different token, the request MUST fail.

- If a resource has a write lock with target ".", the body and
properties of that resource are protected from unauthorized
modification.

If a resource has a write lock with target ".", a request cannot
modify the body or dead properties of that resource unless the
principal of the request owns a write lock with target "." on that
resource and the token of that write lock is specified in an IF
header.

**************************

---

From: "Geoffrey M. Clemm" <[email-masked]>
Date: Wed, 26 Jan 2000 22:35:29 -0500

From: [email-masked]

Where do you find this definition in rfc2518?  The activitelock element
is defined as a 3 to 6 tuple:

   <!ELEMENT activelock (lockscope, locktype, depth, owner?, timeout?,
   locktoken?) >

I have found no occurrence of the term "authentication id" in rfc2518.

Yup (this is fixed in GULP-3).

If you are authenticating against the principal issuing a request,
there is no point in maintaining or requiring a lock token.  If you
are using a lock token to avoid merging between cooperating clients,
then you don't need to authenticate against a principal.  In either
case, there is no point in authenticating the use of a lock token.

And even if there would be a point, it is not specified in rfc2518,
so this would be protocol extension, not protocol compliance.

   - say you have a lock on a resource which translates to a lock on its
   segment binding in its parent collection (the one used to request the
   lock), and the resource itself.

Actually, it produces a lock on all the WebDAV collections named by
segments of the request-URL of the LOCK.

   Now you move the resource to some other
   collection. This removes the lock from the binding in the collection, but
   not the lock on the resource itself?

When you issue a move, the locks are recomputed.  In particular,
(in GULP-3) the rule is:

R5: If a collection C has a lock with token "K" and a request adds
or removes a member from C, all locks with token "K" are removed except for
those that would result from re-executing the LOCK command that
created the token "K" locks.   If any of these locks cannot be added,
the request MUST fail.

   If so, could one expect that a new
   lock would be added to destination binding so that the overall state of the
   system is the same?

In GULP, the lock is logically on the request-URL of the LOCK
request, not on any particular resource.  This logical lock is
reflected in the state of the appropriate resources, so following
a MOVE, the original LOCK request continues to be in effect on the
specified URL.

   The user started out with a protected resource and URL.
   After the move, one would expect the same level of protection?

In GULP, the user started out with a protected URL, and that is the
URL that remains protected following the MOVE.

Cheers,
Geoff