- From: Geoffrey M. Clemm <gclemm@tantalum.atria.com>
- Date: Thu, 7 Oct 1999 12:39:38 -0400
- To: w3c-dist-auth@w3.org
My non-proposal is as follows: Modify RFC-2518 to: - remove depth locks, shared locks, and lock null resources - add a Target-Selector header for reliable access to a locked resource - make simple single resource locking mandantory. This will simplify the implementation of both clients and servers, captures the key functionality that is in use today while deferring the more speculative elements of the protocol. The reason this is a non-proposal is that I'm afraid that the energy that it would require to get this change accepted would detract from what I believe is a more time critical task, namely, producing the DeltaV versioning protocol. But as one last tilt against this particular windmill, I'll include a "diff" indicating how I would change 2518 "if I ran the zoo" (:-). Cheers, Geoff This is similar to "diff -c" format, i.e. the old text comes first, and then the new text. Lines deleted are marked with a "-". Lines added are marked with a "+". Lines changed are marked with an "!". *** Original Text *** Locking: The ability to keep more than one person from working on a ! document at the same time. This prevents the "lost update problem," ! in which modifications are lost as first one author then another ! writes changes without merging the other author's changes. ! ! Null Resource - A resource which responds with a 404 (Not Found) to ! any HTTP/1.1 or DAV method except for PUT, MKCOL, OPTIONS and LOCK. ! A NULL resource MUST NOT appear as a member of its parent collection. 6 Locking --- New Text --- Locking: The ability to keep more than one person from working on a ! document at the same time. This prevents the "update merge problem," ! in which two author concurrently change the same resource, resulting ! in the need to merge the resulting documents. 6 Locking *** Original Text *** access to that resource. Using a lock, an authoring client can provide a reasonable guarantee that another principal will not modify a resource while it is being edited. In this way, a client can ! prevent the "lost update" problem. ! ! This specification allows locks to vary over two client-specified ! parameters, the number of principals involved (exclusive vs. shared) ! and the type of access to be granted. This document defines locking ! for only one access type, write. However, the syntax is extensible, ! and permits the eventual specification of locking for other access ! types. ! ! 6.1 Exclusive Vs. Shared Locks ! ! The most basic form of lock is an exclusive lock. This is a lock ! where the access right in question is only granted to a single ! principal. The need for this arbitration results from a desire to ! avoid having to merge results. ! ! However, there are times when the goal of a lock is not to exclude ! others from exercising an access right but rather to provide a ! mechanism for principals to indicate that they intend to exercise ! their access rights. Shared locks are provided for this case. A ! shared lock allows multiple principals to receive a lock. Hence any ! principal with appropriate access can get the lock. ! ! With shared locks there are two trust sets that affect a resource. ! The first trust set is created by access permissions. Principals who ! are trusted, for example, may have permission to write to the ! resource. Among those who have access permission to write to the ! resource, the set of principals who have taken out a shared lock also ! must trust each other, creating a (typically) smaller trust set ! within the access permission write set. ! ! Starting with every possible principal on the Internet, in most ! situations the vast majority of these principals will not have write ! access to a given resource. Of the small number who do have write ! access, some principals may decide to guarantee their edits are free ! from overwrite conflicts by using exclusive write locks. Others may ! decide they trust their collaborators will not overwrite their work ! (the potential set of collaborators being the set of principals who ! have write permission) and use a shared lock, which informs their ! collaborators that a principal may be working on the resource. ! ! The WebDAV extensions to HTTP do not need to provide all of the ! communications paths necessary for principals to coordinate their ! activities. When using shared locks, principals may use any out of ! band communication channel to coordinate their work (e.g., face-to- ! face interaction, written notes, post-it notes on the screen, ! telephone conversation, Email, etc.) The intent of a shared lock is ! to let collaborators know who else may be working on a resource. ! ! Shared locks are included because experience from web distributed ! authoring systems has indicated that exclusive locks are often too ! rigid. An exclusive lock is used to enforce a particular editing ! process: take out an exclusive lock, read the resource, perform ! edits, write the resource, release the lock. This editing process ! has the problem that locks are not always properly released, for ! example when a program crashes, or when a lock owner leaves without ! unlocking a resource. While both timeouts and administrative action ! can be used to remove an offending lock, neither mechanism may be ! available when needed; the timeout may be long or the administrator ! may not be available. ! ! 6.2 Required Support ! ! A WebDAV compliant server is not required to support locking in any ! form. If the server does support locking it may choose to support ! any combination of exclusive and shared locks for any access types. ! ! The reason for this flexibility is that locking policy strikes to the ! very heart of the resource management and versioning systems employed ! by various storage repositories. These repositories require control ! over what sort of locking will be made available. For example, some ! repositories only support shared write locks while others only ! provide support for exclusive write locks while yet others use no ! locking at all. As each system is sufficiently different to merit ! exclusion of certain locking features, this specification leaves ! locking as the sole axis of negotiation within WebDAV. 6.3 Lock Tokens --- New Text --- access to that resource. Using a lock, an authoring client can provide a reasonable guarantee that another principal will not modify a resource while it is being edited. In this way, a client can ! prevent the "update merge" problem. 6.3 Lock Tokens *** Original Text *** 7.1 Methods Restricted by Write Locks A write lock MUST prevent a principal without the lock from ! successfully executing a PUT, POST, PROPPATCH, LOCK, UNLOCK, MOVE, ! DELETE, or MKCOL on the locked resource. All other current methods, GET in particular, function independently of the lock. Note, however, that as new methods are created it will be necessary --- New Text --- 7.1 Methods Restricted by Write Locks A write lock MUST prevent a principal without the lock from ! successfully executing a PUT, POST, PROPPATCH, LOCK, or UNLOCK ! on the locked resource. A write lock on a collection MUST ! prevent a principal without the lock from successfully creating ! a new internal member or deleting an existing internal member ! of that collection. All other current methods, GET in particular, function independently of the lock. Note, however, that as new methods are created it will be necessary *** Original Text *** 7.2 Write Locks and Lock Tokens ! A successful request for an exclusive or shared write lock MUST result in the generation of a unique lock token associated with the ! requesting principal. Thus if five principals have a shared write ! lock on the same resource there will be five lock tokens, one for ! each principal. 7.3 Write Locks and Properties --- New Text --- 7.2 Write Locks and Lock Tokens ! A successful request for a write lock MUST result in the generation of a unique lock token associated with the ! requesting principal. This lock token can then be specified in ! a Target-Request header to reliably access the locked resource, ! even if the locked resource has been MOVE'd or DELETE'd. 7.3 Write Locks and Properties *** Original Text *** Only dead properties and live properties defined to respect locks are guaranteed not to change while write locked. - 7.4 Write Locks and Null Resources - - It is possible to assert a write lock on a null resource in order to - lock the name. - - A write locked null resource, referred to as a lock-null resource, - MUST respond with a 404 (Not Found) or 405 (Method Not Allowed) to - any HTTP/1.1 or DAV methods except for PUT, MKCOL, OPTIONS, PROPFIND, - LOCK, and UNLOCK. A lock-null resource MUST appear as a member of - its parent collection. Additionally the lock-null resource MUST have - defined on it all mandatory DAV properties. Most of these - properties, such as all the get* properties, will have no value as a - lock-null resource does not support the GET method. Lock-Null - resources MUST have defined values for lockdiscovery and - supportedlock properties. - - Until a method such as PUT or MKCOL is successfully executed on the - lock-null resource the resource MUST stay in the lock-null state. - However, once a PUT or MKCOL is successfully executed on a lock-null - resource the resource ceases to be in the lock-null state. - - If the resource is unlocked, for any reason, without a PUT, MKCOL, or - similar method having been successfully executed upon it then the - resource MUST return to the null state. - 7.5 Write Locks and Collections ! A write lock on a collection, whether created by a "Depth: 0" or ! "Depth: infinity" lock request, prevents the addition or removal of ! member URIs of the collection by non-lock owners. As a consequence, when a principal issues a PUT or POST request to create a new resource under a URI which needs to be an internal member of a write locked collection to maintain HTTP namespace consistency, or issues a --- New Text --- Only dead properties and live properties defined to respect locks are guaranteed not to change while write locked. 7.5 Write Locks and Collections ! A write lock on a collection prevents the addition or removal of ! immediate member URIs of the collection by non-lock owners. As a consequence, when a principal issues a PUT or POST request to create a new resource under a URI which needs to be an internal member of a write locked collection to maintain HTTP namespace consistency, or issues a *** Original Text *** internal member URI of a write locked collection, this request MUST fail if the principal does not have a write lock on the collection. - However, if a write lock request is issued to a collection containing - member URIs identifying resources that are currently locked in a - manner which conflicts with the write lock, the request MUST fail - with a 423 (Locked) status code. - - If a lock owner causes the URI of a resource to be added as an - internal member URI of a locked collection then the new resource MUST - be automatically added to the lock. This is the only mechanism that - - allows a resource to be added to a write lock. Thus, for example, if - the collection /a/b/ is write locked and the resource /c is moved to - /a/b/c then resource /a/b/c will be added to the write lock. - 7.6 Write Locks and the If Request Header If a user agent is not required to have knowledge about a lock when --- New Text --- internal member URI of a write locked collection, this request MUST fail if the principal does not have a write lock on the collection. 7.6 Write Locks and the If Request Header If a user agent is not required to have knowledge about a lock when *** Original Text *** 7.7 Write Locks and COPY/MOVE A COPY method invocation MUST NOT duplicate any write locks active on ! the source. However, as previously noted, if the COPY copies the ! resource into a collection that is locked with "Depth: infinity", ! then the resource will be added to the lock. ! ! A successful MOVE request on a write locked resource MUST NOT move ! the write lock with the resource. However, the resource is subject to ! being added to an existing lock at the destination, as specified in ! section 7.5. For example, if the MOVE makes the resource a child of a ! collection that is locked with "Depth: infinity", then the resource ! will be added to that collection's lock. Additionally, if a resource ! locked with "Depth: infinity" is moved to a destination that is ! within the scope of the same lock (e.g., within the namespace tree ! covered by the lock), the moved resource will again be a added to the ! lock. In both these examples, as specified in section 7.6, an If ! header must be submitted containing a lock token for both the source ! and destination. 7.8 Refreshing Write Locks --- New Text --- 7.7 Write Locks and COPY/MOVE A COPY method invocation MUST NOT duplicate any write locks active on ! the source. ! ! A successful MOVE request on a write locked resource MUST move ! the write lock with the resource. 7.8 Refreshing Write Locks *** Original Text *** <D:resourcetype><D:collection/></D:resourcetype> <D:supportedlock> <D:lockentry> - <D:lockscope><D:exclusive/></D:lockscope> - <D:locktype><D:write/></D:locktype> - </D:lockentry> - <D:lockentry> - <D:lockscope><D:shared/></D:lockscope> <D:locktype><D:write/></D:locktype> </D:lockentry> </D:supportedlock> --- New Text --- <D:resourcetype><D:collection/></D:resourcetype> <D:supportedlock> <D:lockentry> <D:locktype><D:write/></D:locktype> </D:lockentry> </D:supportedlock> *** Original Text *** <D:resourcetype/> <D:supportedlock> <D:lockentry> - <D:lockscope><D:exclusive/></D:lockscope> - <D:locktype><D:write/></D:locktype> - </D:lockentry> - <D:lockentry> - <D:lockscope><D:shared/></D:lockscope> <D:locktype><D:write/></D:locktype> </D:lockentry> </D:supportedlock> --- New Text --- <D:resourcetype/> <D:supportedlock> <D:lockentry> <D:locktype><D:write/></D:locktype> </D:lockentry> </D:supportedlock> *** Original Text *** specific properties assert that "container" was created on December 1, 1997, at 5:42:21PM, in a time zone 8 hours west of GMT (creationdate), has a name of "Example collection" (displayname), a ! collection resource type (resourcetype), and supports exclusive write ! and shared write locks (supportedlock). The resource http://www.foo.bar/container/front.html has nine properties defined on it: --- New Text --- specific properties assert that "container" was created on December 1, 1997, at 5:42:21PM, in a time zone 8 hours west of GMT (creationdate), has a name of "Example collection" (displayname), a ! collection resource type (resourcetype), and supports write locks ! (supportedlock). The resource http://www.foo.bar/container/front.html has nine properties defined on it: *** Original Text *** "text/html" (getcontenttype), an entity tag of "zzyzx" (getetag), was last modified on Monday, January 12, 1998, at 09:25:56 GMT (getlastmodified), has an empty resource type, meaning that it is not ! a collection (resourcetype), and supports both exclusive write and ! shared write locks (supportedlock). 8.1.3 Example - Using propname to Retrieve all Property Names --- New Text --- "text/html" (getcontenttype), an entity tag of "zzyzx" (getetag), was last modified on Monday, January 12, 1998, at 09:25:56 GMT (getlastmodified), has an empty resource type, meaning that it is not ! a collection (resourcetype), and supports write ! locks (supportedlock). 8.1.3 Example - Using propname to Retrieve all Property Names *** Original Text *** >>Request ! DELETE /container/ HTTP/1.1 Host: www.foo.bar >>Response --- New Text --- >>Request ! DELETE /container/resource3 HTTP/1.1 Host: www.foo.bar >>Response *** Original Text *** In this example the attempt to delete http://www.foo.bar/container/resource3 failed because it is locked, ! and no lock token was submitted with the request. Consequently, the ! attempt to delete http://www.foo.bar/container/ also failed. Thus the ! client knows that the attempt to delete http://www.foo.bar/container/ ! must have also failed since the parent can not be deleted unless its ! child has also been deleted. Even though a Depth header has not been ! included, a depth of infinity is assumed because the method is on a ! collection. 8.8.5 COPY Status Codes --- New Text --- In this example the attempt to delete http://www.foo.bar/container/resource3 failed because it is locked, ! and no lock token was submitted with the request. 8.8.5 COPY Status Codes *** Original Text *** resource MUST NOT succeed if can not be honored by all the URIs through which the resource is addressable. ! 8.10.4 Depth and Locking ! The Depth header may be used with the LOCK method. Values other than ! 0 or infinity MUST NOT be used with the Depth header on a LOCK ! method. All resources that support the LOCK method MUST support the ! Depth header. ! ! A Depth header of value 0 means to just lock the resource specified ! by the Request-URI. ! ! If the Depth header is set to infinity then the resource specified in ! the Request-URI along with all its internal members, all the way down ! the hierarchy, are to be locked. A successful result MUST return a ! single lock token which represents all the resources that have been ! locked. If an UNLOCK is successfully executed on this token, all ! associated resources are unlocked. If the lock cannot be granted to ! all resources, a 409 (Conflict) status code MUST be returned with a ! response entity body containing a multistatus XML element describing ! which resource(s) prevented the lock from being granted. Hence, ! partial success is not an option. Either the entire hierarchy is ! locked or no resources are locked. ! ! If no Depth header is submitted on a LOCK request then the request ! MUST act as if a "Depth:infinity" had been submitted. ! ! 8.10.5 Interaction with other Methods ! ! The interaction of a LOCK with various methods is dependent upon the ! lock type. However, independent of lock type, a successful DELETE of ! a resource MUST cause all of its locks to be removed. ! ! 8.10.6 Lock Compatibility Table ! ! The table below describes the behavior that occurs when a lock ! request is made on a resource. ! ! Current lock state/ | Shared Lock | Exclusive ! Lock request | | Lock ! =====================+=================+============== ! None | True | True ! ---------------------+-----------------+-------------- ! Shared Lock | True | False ! ---------------------+-----------------+-------------- ! Exclusive Lock | False | False* ! ------------------------------------------------------ ! ! Legend: True = lock may be granted. False = lock MUST NOT be ! granted. *=It is illegal for a principal to request the same lock ! twice. ! ! The current lock state of a resource is given in the leftmost column, ! and lock requests are listed in the first row. The intersection of a ! row and column gives the result of a lock request. For example, if a ! shared lock is held on a resource, and an exclusive lock is ! requested, the table entry is "false", indicating the lock must not ! be granted. 8.10.7 Status Codes --- New Text --- resource MUST NOT succeed if can not be honored by all the URIs through which the resource is addressable. ! 8.10.6 Lock Compatibility ! If a resource is locked, any attempt to lock that resource (other ! than to refresh an existing lock) must fail. 8.10.7 Status Codes *** Original Text *** <?xml version="1.0" encoding="utf-8" ?> <D:lockinfo xmlns:D='DAV:'> - <D:lockscope><D:exclusive/></D:lockscope> <D:locktype><D:write/></D:locktype> <D:owner> <D:href>http://www.ics.uci.edu/~ejw/contact.html</D:href> --- New Text --- <?xml version="1.0" encoding="utf-8" ?> <D:lockinfo xmlns:D='DAV:'> <D:locktype><D:write/></D:locktype> <D:owner> <D:href>http://www.ics.uci.edu/~ejw/contact.html</D:href> *** Original Text *** <D:lockdiscovery> <D:activelock> <D:locktype><D:write/></D:locktype> - <D:lockscope><D:exclusive/></D:lockscope> - <D:depth>Infinity</D:depth> <D:owner> <D:href> --- New Text --- <D:lockdiscovery> <D:activelock> <D:locktype><D:write/></D:locktype> <D:owner> <D:href> *** Original Text *** </D:lockdiscovery> </D:prop> ! This example shows the successful creation of an exclusive write lock on resource http://webdav.sb.aol.com/workspace/webdav/proposal.doc. The resource http://www.ics.uci.edu/~ejw/contact.html contains contact information for the owner of the lock. The server has an --- New Text --- </D:lockdiscovery> </D:prop> ! This example shows the successful creation of a write lock on resource http://webdav.sb.aol.com/workspace/webdav/proposal.doc. The resource http://www.ics.uci.edu/~ejw/contact.html contains contact information for the owner of the lock. The server has an *** Original Text *** <D:activelock> <D:locktype><D:write/></D:locktype> - <D:lockscope><D:exclusive/></D:lockscope> - <D:depth>Infinity</D:depth> <D:owner> <D:href> http://www.ics.uci.edu/~ejw/contact.html --- New Text --- <D:activelock> <D:locktype><D:write/></D:locktype> <D:owner> <D:href> http://www.ics.uci.edu/~ejw/contact.html *** Original Text *** opaque fields have not been calculated in the Authorization request header. - 8.10.10 Example - Multi-Resource Lock Request - - >>Request - - LOCK /webdav/ HTTP/1.1 - Host: webdav.sb.aol.com - Timeout: Infinite, Second-4100000000 - Depth: infinity - Content-Type: text/xml; charset="utf-8" - Content-Length: xxxx - Authorization: Digest username="ejw", - realm="ejw@webdav.sb.aol.com", nonce="...", - uri="/workspace/webdav/proposal.doc", - response="...", opaque="..." - - <?xml version="1.0" encoding="utf-8" ?> - <D:lockinfo xmlns:D="DAV:"> - <D:locktype><D:write/></D:locktype> - <D:lockscope><D:exclusive/></D:lockscope> - <D:owner> - <D:href>http://www.ics.uci.edu/~ejw/contact.html</D:href> - </D:owner> - </D:lockinfo> - - >>Response - - HTTP/1.1 207 Multi-Status - Content-Type: text/xml; charset="utf-8" - Content-Length: xxxx - - <?xml version="1.0" encoding="utf-8" ?> - <D:multistatus xmlns:D="DAV:"> - <D:response> - <D:href>http://webdav.sb.aol.com/webdav/secret</D:href> - <D:status>HTTP/1.1 403 Forbidden</D:status> - </D:response> - <D:response> - <D:href>http://webdav.sb.aol.com/webdav/</D:href> - <D:propstat> - <D:prop><D:lockdiscovery/></D:prop> - <D:status>HTTP/1.1 424 Failed Dependency</D:status> - </D:propstat> - </D:response> - </D:multistatus> - - This example shows a request for an exclusive write lock on a - collection and all its children. In this request, the client has - specified that it desires an infinite length lock, if available, - otherwise a timeout of 4.1 billion seconds, if available. The request - entity body contains the contact information for the principal taking - out the lock, in this case a web page URL. - - The error is a 403 (Forbidden) response on the resource - http://webdav.sb.aol.com/webdav/secret. Because this resource could - not be locked, none of the resources were locked. Note also that the - lockdiscovery property for the Request-URI has been included as - required. In this example the lockdiscovery property is empty which - means that there are no outstanding locks on the resource. - - In this example, the nonce, response, and opaque fields have not been - calculated in the Authorization request header. - 8.11 UNLOCK Method The UNLOCK method removes the lock identified by the lock token in --- New Text --- opaque fields have not been calculated in the Authorization request header. 8.11 UNLOCK Method The UNLOCK method removes the lock identified by the lock token in *** Original Text *** In this example, the lock identified by the lock token "opaquelocktoken:a515cfa4-5da4-22e1-f5b5-00a0451e6bf7" is successfully removed from the resource ! http://webdav.sb.aol.com/workspace/webdav/info.doc. If this lock ! included more than just one resource, the lock is removed from all ! resources included in the lock. The 204 (No Content) status code is used instead of 200 (OK) because there is no response entity body. In this example, the nonce, response, and opaque fields have not been calculated in the Authorization request header. --- New Text --- In this example, the lock identified by the lock token "opaquelocktoken:a515cfa4-5da4-22e1-f5b5-00a0451e6bf7" is successfully removed from the resource ! http://webdav.sb.aol.com/workspace/webdav/info.doc. ! The 204 (No Content) status code is used instead of 200 (OK) because there is no response entity body. In this example, the nonce, response, and opaque fields have not been calculated in the Authorization request header. *** Original Text *** --- New Text --- 9.3 Target-Selector Header Target-Selector = The Target-Selector header specifies the URI of a lock token. When a Target-Selector header is present, the resource identifed by the request-URL will be the resource identified by that URL when the lock was issued, which may be different from resource currently identified by that URL. *** Original Text *** Namespace: DAV: Purpose: Describes a lock on a resource. ! <!ELEMENT activelock (lockscope, locktype, depth, owner?, timeout?, locktoken?) > 12.1.2 locktoken XML Element --- New Text --- Namespace: DAV: Purpose: Describes a lock on a resource. ! <!ELEMENT activelock (locktype, owner?, timeout?, locktoken?) > 12.1.2 locktoken XML Element *** Original Text *** Purpose: Defines the types of locks that can be used with the resource. ! <!ELEMENT lockentry (lockscope, locktype) > 12.6 lockinfo XML Element --- New Text --- Purpose: Defines the types of locks that can be used with the resource. ! <!ELEMENT lockentry (locktype) > 12.6 lockinfo XML Element *** Original Text *** Purpose: The lockinfo XML element is used with a LOCK method to specify the type of lock the client wishes to have created. ! <!ELEMENT lockinfo (lockscope, locktype, owner?) > ! ! 12.7 lockscope XML Element ! ! Name: lockscope ! Namespace: DAV: ! Purpose: Specifies whether a lock is an exclusive lock, or a ! shared lock. ! ! <!ELEMENT lockscope (exclusive | shared) > ! ! 12.7.1 exclusive XML Element ! ! Name: exclusive ! Namespace: DAV: ! Purpose: Specifies an exclusive lock ! ! <!ELEMENT exclusive EMPTY > ! ! 12.7.2 shared XML Element ! ! Name: shared ! Namespace: DAV: ! Purpose: Specifies a shared lock ! ! <!ELEMENT shared EMPTY > 12.8 locktype XML Element --- New Text --- Purpose: The lockinfo XML element is used with a LOCK method to specify the type of lock the client wishes to have created. ! <!ELEMENT lockinfo (locktype, owner?) > 12.8 locktype XML Element *** Original Text *** <D:lockdiscovery> <D:activelock> <D:locktype><D:write/></D:locktype> - <D:lockscope><D:exclusive/></D:lockscope> - <D:depth>0</D:depth> <D:owner>Jane Smith</D:owner> <D:timeout>Infinite</D:timeout> <D:locktoken> --- New Text --- <D:lockdiscovery> <D:activelock> <D:locktype><D:write/></D:locktype> <D:owner>Jane Smith</D:owner> <D:timeout>Infinite</D:timeout> <D:locktoken> *** Original Text *** </D:response> </D:multistatus> ! This resource has a single exclusive write lock on it, with an infinite timeout. 13.11 supportedlock Property --- New Text --- </D:response> </D:multistatus> ! This resource has a write lock on it, with an infinite timeout. 13.11 supportedlock Property *** Original Text *** <D:prop> <D:supportedlock> <D:lockentry> - <D:lockscope><D:exclusive/></D:lockscope> <D:locktype><D:write/></D:locktype> </D:lockentry> <D:lockentry> - <D:lockscope><D:shared/></D:lockscope> <D:locktype><D:write/></D:locktype> </D:lockentry> </D:supportedlock> --- New Text --- <D:prop> <D:supportedlock> <D:lockentry> <D:locktype><D:write/></D:locktype> </D:lockentry> <D:lockentry> <D:locktype><D:write/></D:locktype> </D:lockentry> </D:supportedlock>
Received on Thursday, 7 October 1999 12:39:43 UTC