RE: Locking questions

Yaron,

Thanks for the great and detailed response. Some followon questions below in
<jra>...</jra>. I deleted the stuff that had no further questions to reduce
complexity.





w3c-dist-auth-request@w3.org on 07/09/98 07:19:33 PM
Please respond to w3c-dist-auth-request@w3.org
To: w3c-dist-auth@w3.org, ejw@ics.uci.edu
cc:
Subject: RE: Locking questions

> Section 7.10.1, last sentence says: "The response MUST
> contain the value of
> the
> lockdiscovery property in a prop XML element". What exactly is in the
> lockdiscovery property returned on a successful LOCK? Is it
> the activelock
> just
> granted, or the same activelocks that would be returned by a
> lockdiscovery
> PROPFIND? If it is the latter, how would an application
> determine which lock
> token was just granted to the user? The owner element in the
> lockdiscovery
> is
> not sufficient because it does not necessarily indicate the
> credentials of
> the
> owner of the lock but rather gives contact information
> suitable for human
> interpretation. If it is the former, then there's no problem
> as there is
> exactly one locktoken in the lockdiscovery for a successful
> LOCK, and it's
> the
> one just granted.
>

The response must include the current value of the lockdiscovery property.
As the lockdiscovery property lists all locks outstanding against the
resource then the prop element must contain the same list.

The application would determine the appropriate lock token by examining the
response and finding the lock entry that matches what it requested. Thus if
you asked for an exclusive write lock and got back a 200 response then the
lock token associated with the exclusive write lock must be yours. The same
logic applies to shared write locks. There is no possibility of ambiquity
for write locks. If another lock type does have the possibility of ambiquity
then it will have to add additional response elements to compensate.

<jra>
But there may be many shared locks in the lockdiscovery property. How would an
application figure out which one was the one just created for this user? I see
that it works with exclusive locks because there can only be one.
</jra>

> In a follow-up question to the above, how would an application
> programatically
> determine the credentials (the user id from the Authorization
> header using
> the
> Basic or Digest authorization scheme)? A lockdiscovery
> PROPFIND will return
> the
> owner, but this isn't necessarily the authorization credentials? Is it
> intended
> to hide this information? If so, then applications are responsible for
> retaining locktokens for all resources they have locked until
> they no longer
> need them. For example, if an application obtained an
> exclusive write lock
> on a
> resource with infinite time-out, and subsequently lost the
> locktoken, there
> would be no way for the owner to unlock the resource without
> becoming the
> admin
> user.
>

Auth schemes are a nasty business without any rule on how one can reliably
identify a particular principal. Thus DAV choose to side step the problem
for the moment feeling that a useful system could be implemented without
having to provide a mechanism for identifying principals. Part of this "side
step" however was accepting the responsibility to solve the problem as part
of the DAV ACL effort. Two drafts, one on requirements and another on a
potential implementation are available in the drafts directory.

However there is a temporary hack which can be used until the ACL draft is
standardized. The Owner element is completely specified by the client and
may contain anything. Thus one can imagine an application submitting an
owner element of the form: <owner>This lock was taken out by
Michael<unique-id><href>guid:1234-4342-234-234234</href></unique-id></owner>

<jra>
But DAV did specify Basic (with SSL) and Digest authorization schemes must be
supported for security. They both provide the principal userid. Couldn't this
be used?

Next, the temporary hack couldn't be relied upon as not all servers would
necessarily do it the same way.

So I still don't see how an application can get the lock token from the lock it
just requested.
</jra>

> Section 6.5 describes the problem of race conditions
> resulting from multiple
> concurrent processes acting under the same principal on the
> same resources.
> I
> do not understand why requiring locktokens for all resources
> modified by a
> method solves this problem. I assume a scenario like the
> following would be
> typical: Program A takes out a lock on Resource A for User A,
> and retains
> the
> lock token returned by the LOCK method. At some subsequent
> point it time,
> Program A communicates the locktoken to another program,
> Program B, also run
> by
> User A, as Program B cannot discover the locktoken itself
> (due to the issues
> described above). Now Program A and Program B are equally
> able to modify
> Resource A. Resource A is it is locked by User A, and both
> Program A and
> Program
>  B have the locktoken. So it would seem that section 6.5 does
> not describe a
> mechanism for preventing these collisions, it only provides a
> possibility
> for
> programs to use the communication of locktokens as sync points for
> concurrent
> activities. It seems it is still the applications' responsibility to
> coordinate
> their updates appropriately through some out-of-band activity
> like monitors,
> semaphores, etc. Am I missing something?
>

To reiterate, program B could have discovered the lock token without having
to first check with program A by examining the owner element and checking
for any unique info that had been previously agreed upon. Once the ACL
standard is completed it will also be possible to include unique principal
identifiers.

In answer to your question, the scenario we are trying to prevent is not the
one you identify. If two programs both have the lock token and have been
authorized by the user to use the lock token then they are free to run rough
shod over each other. It is up to the user to make sure that they don't give
two seperate applications the ability to simultaneously access a locked
resource. For example, imagine you are editing a file in your favorite
editor and so have locked the file. You then go to the command prompt and
order that the file you are editing be moved. The move command will return
an error since it doesn't have the lock token. However the move program may
be smart enough to to do a lockdiscovery check, examine the owner element,
realize that you are the one who locked the file and offer to move the file
for you anyway. However it will first warn you that it is about to move a
file that another program has locked. If you still choose to allow the move
then you must also live with the consequences.

Thus the purpose of requiring the inclusion of the lock token is strictly to
prevent the scenario described in section 6.5.

<jra>
I thought I was describing the same scenario as section 6.5, but I think I see
what you're getting at. The point is that you don't want the move to just
happen by implicitly recognizing that the user is the owner of the lock. You
want it to have to explicitly get the lock token if the resource is locked, and
use the knowledge that one exists and that this process had to go get it (it
didn't actually do the lock) to warn the user that some other process actually
took out the lock and may be still active. This makes perfect sense.
</jra>

> Section 6.5 says "... a lock token MUST be submitted by an authorized
> principal
> in the If header for all locked resources that a method may
> interact with or
> the method MUST fail." Should this have been "... all locked
> resources that
> a
> method may modify or the method MUST fail"? The example
> follows this rule as
> the lock token destination is the only one required for the
> COPY method. If
> this is the case, what about resource that are indirectly
> modified by a
> method?
> Do their lock tokens have to be provided too? For example, consider a
> collection that is not depth locked, but contains a resource
> that has an
> exclusive lock. Deleting the collection causes the locked
> resource contained
> in
> it to be modified. Does the DELETE method have to have an If header
> containing
> the locked resource as well as the collection?
>

"...for all locked resources that a method may interact with..." If you are
deleting a collection which contains a locked resource then obviously the
method effects that resource and so its lock token must be included.

<jra>
So applications may be getting and retaining a lot of lock tokens. Makes for
pretty complicated client applications. Again, I don't understand how an
application can identify the correct lock from the lockdiscovery anyway.
</jra>


> Section 6.6 says "A MOVE MUST NOT move the write lock with
> the resource...".
> But it doesn't say what happens if this is attempted. Does
> the move fail on
> this resource, or does the move occur and the lock is
> removed? I assume the
> move fails on this resource but continues to move as many resources as
> possible. So for example, if a user attempts to move a
> collection that is
> unlocked, but contains a resource locked by another user, the
> collection is
> moved, but not the locked resource. What if the resource is
> locked by the
> user
> doing the move? Is the resource moved in this case? If so, is the lock
> retained? It would be surprising if a user lost his locks
> when moving a
> collection.
>

All locks are lost when moving ANY resource, collection or not. The
specification does not prevent success when moving a locked resource however
any success will mean that the lock was lost.

<jra>
Seems to violate the principle of least astonishment. So in the example above,
the collection, and the locked resource(s) in it are moved successfully, and
the lock is deleted? If locks are lost on a move, why bother having the lock
tokens in the If header? Could users subvert locking by moving the resource to
another location, editing it, and then moving it back?
</jra>

And finally, a new question: section 6.1 indicates what methods cannot be
successfully executed on a locked resource by principals without the lock. Why
is POST specified. The POST method in the spec makes no mention of locking, and
there is no status code returned for a locked resource. Since the actual
semantics of POST aren't specified and are server dependent, it would seem that
DAV locks can't apply. The POST may not write anything anyway.

COPY is missing, but was used in the example on locking in section 6.5.1.

Finally, LOCK itself can't be included in the list because you can't have a
lock before requesting one, i.e., you can't request the same lock twice.

Again, thanks for the help.

Received on Thursday, 9 July 1998 20:59:55 UTC