Subject: [Bug 23] lock discovery vs shared locks

From: [email-masked]
Date: Sat, 15 Oct 2005 11:29:07 -0700

http://ietf.cse.ucsc.edu:8080/bugzilla/show_bug.cgi?id=23

[email-masked] changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |ASSIGNED

------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.

---

From: Julian Reschke <[email-masked]>
Date: Sat, 15 Oct 2005 20:51:43 +0200

Proposed resolution for 
<http://ietf.cse.ucsc.edu:8080/bugzilla/show_bug.cgi?id=23>:

Section 6., para. 14:
OLD:

    A lock token is a type of state token, represented as a URI, which
    identifies a particular lock.  A lock token is returned in the Lock-
    Token header in the response to a successful LOCK operation.  The
    lock token also appears in the value of the lockdiscovery property,
    the value of which is returned in the body of the response to a
    successful LOCK operation (this property also includes the tokens of
    other current locks on the resource).  Finally, the lockdiscovery
    property can be queried using PROPFIND and the token can be
    discovered that way.  Each lock has only one unique lock token.

NEW:

    A lock token is a type of state token, represented as a URI, which
    identifies a particular lock.  Each lock has exactly one unique lock
    token, which is returned upon a successful LOCK creation operation in
    the "Lock-Token" response header defined in Section 9.6.

Best regards, Julian

--- draft-ietf-webdav-rfc2518bis-07.xml	2005-10-15 19:19:46.000000000 +0100
+++ rfc2518bis-08-bug23.xml	2005-10-15 19:48:16.000000000 +0100
@@ -616,17 +616,13 @@
   </section>
   
   <section title="Lock Tokens">
-    <t>
-   A lock token is a type of state token, represented as a URI, which 
-   identifies a particular lock.  A lock token is returned in the Lock-
-   Token header in the response to a successful LOCK operation. The 
-   lock token also appears in the value of the lockdiscovery property, 
-   the value of which is returned in the body of the response to a 
-   successful LOCK operation (this property also includes the tokens of 
-   other current locks on the resource).  Finally, the lockdiscovery 
-   property can be queried using PROPFIND and the token can be 
-   discovered that way. Each lock has only one unique lock token.  
-    </t>
+  <t>
+   A lock token is a type of state token, represented as a URI, which
+   identifies a particular lock.  Each lock has exactly one unique lock
+   token, which is returned upon a successful LOCK creation operation in
+   the "Lock-Token" response header defined in
+   <xref target="HEADER_Lock-Token"/>.
+  </t>
     <t>
    Lock token URIs MUST be unique across all resources for all time. 
    This uniqueness constraint allows lock tokens to be submitted across 
@@ -3337,7 +3333,7 @@
     </section>
   </section>
   
-  <section title="Lock-Token Header">
+  <section title="Lock-Token Header" anchor="HEADER_Lock-Token">
     <t>
    Lock-Token = "Lock-Token" ":" Coded-URL 
     </t>

---

From: Elias Sinderson <[email-masked]>
Date: Thu, 27 Oct 2005 10:58:02 -0700

Julian Reschke wrote:

> Proposed resolution for 
> <http://ietf.cse.ucsc.edu:8080/bugzilla/show_bug.cgi?id=23>: [...]
> NEW:

I have no issues with the proposed text.

Cheers,
Elias

---

From: Lisa Dusseault <[email-masked]>
Date: Fri, 28 Oct 2005 15:48:52 -0700

> I have no issues with the proposed text.
It's not just the Lock-Token response header that shows the lock token 
in response to LOCK, the token also appears in the lockdiscovery 
property value, which is included in the body of the LOCK response.   
There's a couple issues that the section on lock tokens should address:
  - how lock tokens relate to locks (one and only one)
  - who generates them, how, and requirements (uniqueness, that clients 
MUST not interpret)
  - where to get them (Lock-Token response, lockdiscovery property)

So here's the (work-in-progress) text for the whole section on lock 
tokens, including my attempts to incorporate several bits of suggested 
text in a readable order, while also being complete:

----

  A lock token is a type of state token, represented as a URI, which 
identifies a particular lock. Each lock has exactly one unique lock 
token generated by the server. Clients MUST NOT attempt to interpret 
lock tokens in any way.

Lock token URIs MUST be unique across all resources for all time. This 
uniqueness constraint allows lock tokens to be submitted across 
resources and servers without fear of confusion.

When a LOCK operation creates a new lock, the new lock token is 
returned in the Lock-Token response header defined in Section 9.6 
(Lock-Token Header), and also in the body of the response. Also note 
that lock tokens MUST appear in the 'lockdiscovery' property of a 
locked resource.

Submitting a lock token does not confer full privilege to use the lock 
token or modify the locked resource. Anyone can find out anyone else's 
lock token by performing lock discovery. Write access and other 
privileges MUST be enforced through normal privilege or authentication 
mechanisms, not based on the slight obscurity of lock token values.

Since lock tokens are unique, a client MAY submit a lock token in an If 
header on a resource other than the one that returned it.

This specification encourages servers to create UUIDs for lock tokens, 
and to use the URI form defined by Universal Unique Identifier (UUID)  
[9]. However servers are free to use another valid URI so long as it 
meets the uniqueness requirements. For example, a valid lock token 
might be constructed using the "opaquelocktoken" scheme defined in an 
appendix of this document.

Example: "urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6"

----

There were some comments in a previous email from Julian about how the 
lock token might not appear in the 'lockdiscovery' property if there 
are multiple (shared) locks on the resource.  This statement doesn't 
fit my understanding, so I haven't yet "fixed" that if I am indeed 
wrong.  Doesn't the 'lockdiscovery' property include every active lock 
on the resource and all their lock tokens?

Lisa

---

From: Geoffrey M Clemm <[email-masked]>
Date: Fri, 28 Oct 2005 23:20:32 -0400

The last sentence is incorrect.  A lock token appears in a PROPFIND
lockdiscovery only if the server wishes to expose it.  I have argued
in the past that a sensible server should never expose a lock token in a
PROPFIND lockdiscovery, since it just allows a client of a user 
to incorrectly re-use a lock token still in use by another client
of that user.  So if we say anything, it should "A server SHOULD NOT
include a lock token in a PROPFIND lockdiscovery, since it introduces
the possibility of two clients of a given user overwriting each others
changes".

Cheers,
Geoff

Lisa wrote on 10/28/2005 06:48:52 PM:

> >>    token, which is returned upon a successful LOCK creation operation 

> >> in

---

From: Julian Reschke <[email-masked]>
Date: Sat, 29 Oct 2005 10:39:23 +0200

> property value, which is included in the body of the LOCK response. 

Yes. But does this need to be stated here? The right place to state it 
are the definitions for the LOCK method and the DAV:lockdiscovery 
property. Why repeat it here?

> When a LOCK operation creates a new lock, the new lock token is returned 
> in the Lock-Token response header defined in Section 9.6 (Lock-Token 
> Header), and also in the body of the response. Also note that lock 
> tokens MUST appear in the 'lockdiscovery' property of a locked resource.

I don't see any benefit of stating this here. What clients are 
interested in is how to get the lock token once they issues the LOCK, 
and the *only* correct answer to that is to use the response header.

Mentioning a different mechanism here would at least require to make 
statements about when it won't work (shared locks), leading to even more 
spec text & confusion.

> [9]. However servers are free to use another valid URI so long as it 

That reference seems to use the wrong title, the spec is called "A 
Universally Unique IDentifier (UUID) URN Namespace".

> meets the uniqueness requirements. For example, a valid lock token might 
> be constructed using the "opaquelocktoken" scheme defined in an appendix 
> of this document.
> 

Example and text don't match.

> lock token might not appear in the 'lockdiscovery' property if there are 
> multiple (shared) locks on the resource. This statement doesn't fit my 
> understanding, so I haven't yet "fixed" that if I am indeed wrong. 
> Doesn't the 'lockdiscovery' property include every active lock on the 
> resource and all their lock tokens?

Yes.

Best regards, Julian

---

From: Julian Reschke <[email-masked]>
Date: Sat, 29 Oct 2005 10:43:39 +0200

> the possibility of two clients of a given user overwriting each others

Here I'll disagree with Geoff :-)

"lock stealing" is further controlled (or can be controlled) by checking 
the principal as well.

I *do* agree that it makes sense to have one coherent section that gives 
advice on how not to reveal lock tokens. For instance, servers are 
allowed to report the locks, but not to disclose the lock tokens (see 
<http://greenbytes.de/tech/webdav/rfc2518.html#rfc.section.12.1>).

Best regards, Julian

---

From: Geoffrey M Clemm <[email-masked]>
Date: Sat, 29 Oct 2005 08:32:23 -0400

The likelihood of damage from lock stealing can be decreased by
only allowing a given user/principal to steal his own locks, but
(as indicated in my original message below :-) it does not prevent
two clients of a given user/principal from overwriting each others
changes.  Since there is a completely safe way of handling this
scenario (i.e., streaming an UNLOCK/LOCK sequence to the server),
I maintain my position that a client should never "steal"
a lock by discovering the lock-token via PROPFIND, even if that
lock was held by another client of that same user, and therefore
lock tokens should never be exposed in a PROPFIND.

Cheers,
Geoff

---

From: Julian Reschke <[email-masked]>
Date: Sat, 29 Oct 2005 15:12:06 +0200

> changes.  Since there is a completely safe way of handling this

Partly correct. Some clients put stuff into DAV:owner in order to ensure 
that they can recognize the locks they created, but of course that's 
lame compared to just remembering which locks one created in the first 
place.

> lock tokens should never be exposed in a PROPFIND.

Well, from a purely theoretical point of view, I agree. In practice, 
clients do lock discovery instead of keeping track of their locks on 
their own, so these clients wouldn't work in this case.

BTW: if a server does not want to expose lock tokens, it can also show 
the locks, but leave out the DAV:locktoken child element. Anyway, this 
is certainly a topic where on coherent paragraph would make a lot of sense.

Best regards, Julian

---

From: Julian Reschke <[email-masked]>
Date: Sat, 29 Oct 2005 15:15:36 +0200

Clarifying one thing on second read:

Lisa Dusseault wrote:
>...

No, what I said (or meant to say is) that looking at DAV:lockdiscovery 
in general will not help you at all, because it may contain *multiple* 
entries (Geoff correctly pointed out later that it may not be there at all).

The only *reliable* way to find out the lock token a LOCK request 
created is to look at the "Lock-Token" response header. This is the only 
method that will always work, so please let's not waste time confusing 
people by talking about other methods that may or may not work.

> resource and all their lock tokens?

It includes whatever the server wants to reveal. Citing 
<http://greenbytes.de/tech/webdav/rfc2518.html#rfc.section.13.8>:

"The server is free to withhold any or all of this information if the 
requesting principal does not have sufficient access rights to see the 
requested data."

Best regards, Julian

---

From: Lisa Dusseault <[email-masked]>
Date: Sat, 29 Oct 2005 08:42:34 -0700

On Oct 29, 2005, at 6:15 AM, Julian Reschke wrote:

>> There were some comments in a previous email from Julian about how 
>> the lock token might not appear in the 'lockdiscovery' property if 
>> there are multiple (shared) locks on the resource. This statement 
>> doesn't fit my
>
> created is to look at the "Lock-Token" response header. This is the 
> only method that will always work, so please let's not waste time 
> confusing people by talking about other methods that may or may not 
> work.
>
Ok, I understand now why the lockdiscovery property is unreliable for 
this purpose.  But what about the body of the LOCK response (in 
addition to the Lock-Token header)?

Lisa

---

From: Julian Reschke <[email-masked]>
Date: Sat, 29 Oct 2005 17:58:38 +0200

Lisa Dusseault wrote:
> this purpose.  But what about the body of the LOCK response (in addition 
> to the Lock-Token header)?

It's the same: 
<http://greenbytes.de/tech/webdav/rfc2518.html#rfc.section.8.10.1>:

"The response MUST contain the value of the lockdiscovery property in a 
prop XML element."

Best regards, Julian

---

From: Lisa Dusseault <[email-masked]>
Date: Sat, 29 Oct 2005 09:05:39 -0700

On Oct 29, 2005, at 8:58 AM, Julian Reschke wrote:

> "The response MUST contain the value of the lockdiscovery property in 
> a prop XML element."
>
> Best regards, Julian
>
>
Yes, and MUST the lock token appear in that context? This is important 
because some clients pull the lock token value from the body of the 
request.  When we tested this in interop testing, we found some clients 
used the body and some used the header, and we had decided at that 
point to allow that to continue happening and make servers put the 
token in both places.

Lisa

---

From: Julian Reschke <[email-masked]>
Date: Sat, 29 Oct 2005 18:12:19 +0200

> Yes, and MUST the lock token appear in that context? This is important 

Again, it's the same. So no, it doesn't have to. It's all in RFC2518.

> request.  When we tested this in interop testing, we found some clients 

That's a bug. The best way to keep people from doing it is to tell them 
to use the Lock-Token response header.

> used the body and some used the header, and we had decided at that point 
> to allow that to continue happening and make servers put the token in 
> both places.

Who is "we" in this context?

Best regards, Julian

---

From: Geoffrey M Clemm <[email-masked]>
Date: Sat, 29 Oct 2005 23:55:52 -0400

To be clear, I am completely in favor of a server exposing all of
the locks on a resource to an authorized user ... I am only against
revealing the lock-token in the information on the lock.

As for clients that use lock-discovery instead of keeping track of
lock tokens, their implementor clearly didn't understand the purpose
of a lock token (preventing a user from overwriting his own changes from
another of his clients), and the specification should make this mistake
clear, and not encourage it.

So I agree with Julian's final suggestion that this issue merits a
paragraph guiding clients on how to use lock tokens properly, and
guiding servers on how to deal with poorly implemented clients.

Cheers,
Geoff

---

From: Lisa Dusseault <[email-masked]>
Date: Sun, 30 Oct 2005 07:51:58 -0800

I mostly agree with this, except with the problem of failed clients.  
If I use a WebDAV client that crashes and loses its locks, or has a bug 
and fails to unlock -- or if I'm testing client or server software -- I 
need a way to get the lock token to remove it as a last resort.

So yes, while clients SHOULD get the lock token on LOCK response and 
remember it, there needs to be a way to recover without administrator 
intervention.

Lisa

---

From: Geoffrey M Clemm <[email-masked]>
Date: Mon, 31 Oct 2005 08:57:04 -0500

I agree that one needs to deal with the problem of failed clients,
but the correct way for the client to do so is with an
UNLOCK/LOCK sequence, and not by using a lock token that it obtains
from a PROPFIND.  This handles the case where it turns out that the
original client hadn't failed, but was just suspended.  With an 
UNLOCK/LOCK
sequence, the original client will get a failure on PUT because
its lock token is no longer valid.  With a re-use of the lock token
obtained with a PROPFIND, the original client's PUT will succeed
and overwrite changes made by the client that stole the lock token.

Cheers,
Geoff