The WebDAV ACL specification defines how to retrieve and interpret ACL and principal information, as well as how to modify some of that information. We begin with the task of retrieval and interpretation. That will provide a framework to understand how to modify access control information. 13.2.1 Principal URLsIn WebDAV ACL support, principal IDs are in the form of an HTTP URL. In fact, the principal URL is the address for a WebDAV resource that represents a user and can be queried with PROPFIND. Principal resources exist inside principal collections, which are also WebDAV resources. This is just an easy way to represent principals in a familiar way so that clients can access them easily. Not much can really be done with principal resources. It's not expected that clients will be allowed to copy, move, delete, or create new principal resources. A principal resource must of course have all of the standard WebDAV resource properties, plus a special property displayname. Thus, a client can easily retrieve an appropriate string for displaying a principal in the UI: Send a PROPFIND request to the principal URL and ask for the displayname value. Groups are also represented as principal resources. A group isn't the same thing as a principal collection, which just exists as a collection containing principals. A principal resource will likely exist in one principal collection only but be a member of several groups. To represent members, a group resource has a group-member-set property containing the principal URLs of its members. A principal (user or group) also has a property called group-membership listing all the groups that the principal is a member of. The collections containing groups and users can be organized a number of ways. One simple way is to identify one collection for all users and another for all groups.
13.2.2 Identifying a Resource OwnerIf each resource has an owner, it's pretty important to see who that owner is. The owner property on a resource contains the principal URL of the user who owns and can administer the resource. The principal URL appears inside an href element, which is a standard WebDAV syntax for an HTTP URL. The client can use PROPFIND to request the owner property. The response contains the owner property value, as shown in Listing 13-1. This PROPFIND response fragment shows that the user identified by http://www.example.org/principals/ids/alice is the owner of the hr/ collection. This HTTP URL is the principal ID, but it's also a real WebDAV resource address. As I'll show in Section 13.4.5, that URL can also be used to query the resource it names, to retrieve a minimal set of information about the user it identifies. The URL that uniquely identifies a user or any other principal is called the principal URL. Listing 13-1 Owner property in partial PROPFIND response.<D:response> <D:href>http://www.example.com/hr/</D:href> <D:propstat> <D:prop> <D:owner> <D:href>http://www.example.com/principals/ids/alice </D:href> </D:owner> </D:prop> <D:status>HTTP/1.1 200 OK</D:status> </D:propstat> </D:response> The owner property may be a rather widely available piece of information, depending on a system's policy. Users who can read a file sometimes need to see who the owner is to ask that the permissions be changed. It's common for this property to be visible to any principal who can read the resource. 13.2.3 Getting ACLsSince each resource has a single ACL, retrieving the ACL is done through a simple PROPFIND for the acl property. Each acl property contains a number of ace elements, one for each principal to whom access privileges are granted or denied (see Listing 13-2). Listing 13-2 Example value for acl property.<D:acl> <D:ace> <D:principal> <D:href>http://www.example.com/principals/ids/hr-group/ </D:href> </D:principal> <D:grant> <D:privilege> <D:write/> </D:privilege> </ D:grant> </D:ace> <D:ace> <D:principal> <D:all/> </D:principal> <D:grant> <D:privilege> <D:read/> </D:privilege> </ D:grant> </D:ace> </D:acl> In this example, the hr-group (and all its members) may write the resource, and all principals may read the resource. That means that members of the hr-group can also read the resource. Although the read privilege can be explicitly granted to the group, it need not be. 13.2.4 Privileges VaryNot all systems have privileges as straightforward as "read" and "write." In fact, read and write aren't that simple themselves. Does "read" mean that the user can read the resource body? Can the user read the resource properties? Can the user read the acl property? On some systems, the answer would be yes, but on most systems, access to the acl property is not granted to all users with access to the resource body. The ACL designers quickly realized that with privileges, one size does not fit all. Nobody could agree on a single list of privileges with well-defined meanings. Some systems had as few as three or four privileges on a resource, while others had closer to 20. Some pure WebDAV implementations had already exposed access control through some nonstandard method such as Web-based administration pages. Other WebDAV implementations were built to expose a pre-existing file system, complete with its ACL information. For example, Apache permissions have always been respected by mod_dav, and MS IIS5 exposed resources in NTFS with NTFS ACLs. There is necessarily a semantic gap between any standard list of privilege definitions and the "real world" as found in various file systems and repositories. If a WebDAV resource is an object that can be exposed through other protocols as well (FTP, SMB, CIFS), it's very important that the permissions be consistent across all protocols. It's already hard enough to administer permissions correctly without having variation in what permissions are granted through different protocols. The complexity of existing systems leads to the requirement for a very flexible system for specifying what privileges can be granted. Thus, the privilege list on a server can be defined by that server and published so that client software can see what privileges may be granted or denied on that server. The ACL specification can attempt to define a standard list of privileges, but some implementations will deviate from the standard list. 13.2.5 Standard PrivilegesThe WebDAV ACL specification does define a list of standard privileges, because if a server can support the standard list, client interoperability with that server should be easier. A standard list of privileges can be very simple and coarse; for example, read, write, and administer. At the other extreme, a standard list of privileges could attempt to be more granular than any actual implementation by defining a large number of extremely specific privileges. The WebDAV ACL specification took the Goldilocks approach, attempting to come up with a reasonable list of privileges, not too coarse and not too granular.
Note that two of these standard privileges contain others. That's because it might be syntactically and semantically possible to grant all but deny write-acl. The all privilege is a shortcut to make setting access control easier. The "'write" privilege contains both write-properties and write-content.
13.2.6 Privilege CompositionThe standard list of privileges can also serve as a basis for understanding a custom list of privileges. A custom list of privileges probably has at least some relationship to standard concepts like "read" and "write." Therefore, the WebDAV ACL specification defines a way to show these relationships. Servers can advertise how their custom ACL model maps to the standard privileges.
Based on the WebDAV standard privileges, which are not too coarse and not too granular, there are four basic approaches for a server implementation:
Since the server must advertise what privileges it supports and how its custom privileges relate to standard privileges, WebDAV ACLs define a property to advertise this information. The property with this information is the supported-privilege-set property. It can have a different value on each resource in a repository because the repository may have different privileges defined for collections, regular resources, or other resource types. The supported-privilege-set property contains a tree of supported-privilege elements, including every one of the standard privileges. The tree is a way of showing hierarchy.
If a custom privilege is a composition including an abstract standard privilege, then that standard privilege can only be granted by granting the custom privilege. This also grants whatever else that concrete privilege entails. For example, a server may define read-acl as abstract, and define the concrete privilege administer as a superset of read-acl. From this definition of administer, the client can understand that granting the administer privilege will include the permission to read ACLs. If an abstract standard privilege contains custom privileges, then the custom privileges are a subset of the standard privilege. To get the effect of granting the standard privilege, grant all the concrete privileges that it contains. For example, a server may define read as abstract, and define the concrete privileges read-content and read-comments as subsets of the read privilege. From this definition, the client can understand that in order to grant read, it must grant both read-content and read-comments. Listing 13-3 is a full example value for the supported-privilege-set property. This example illustrates a server implementation with very simplistic and limited permissions, only supporting read, write, and the custom privilege administer. Most of the standard privileges are declared as abstract or not directly supported. Listing 13-3 Example value for supported-privilege-set.<supported-privilege-set xmlns="DAV:"> <supported-privilege> <privilege> <all/> </privilege> <abstract/> <supported-privilege> <privilege> <read> </privilege> </supported-privilege> <supported-privilege> <privilege> <write/> </privilege> <supported-privilege> <privilege> <write-properties/> </privilege> <abstract/> </supported-privilege> <supported-privilege> <privilege> <write-content/> </privilege> <abstract/> </supported-privilege> </supported-privilege> </supported-privilege> <supported-privilege> <privilege><C:administer xmlns:C="http:// www.example.com/"/> </privilege> <description xml:lang="en">Administer the permissions and locks of this resource</description> <supported-privilege> <privilege> <read-acl/> </privilege> <abstract/> </supported-privilege> <supported-privilege> <privilege> <write-acl/> </privilege> <abstract/> </supported-privilege> <supported-privilege> <privilege><read-current-user-privilege-set/> </privilege> <abstract/> </supported-privilege> <supported-privilege> <privilege> <unlock/> </privilege> <abstract/> </supported-privilege> </supported-privilege> </supported-privilege-set> Note that all privileges are abstract except read, write, and the custom administer privilege. The custom privilege is defined in the http://www.example.com/ namespace, not in the DAV: namespace. Here's an English explanation of this example:
Figure 13-1 is another way to view the same supported-privilege-set property value. The read, write, and administer privileges the only privileges that can be granted are shown in bold. All of the privileges in the model are directly from the ACL standard except the administer privilege, which is custom. Figure 13-1. Privilege containment.Based on these relationships, a client ought to be able to take the user's intent, and as long as it's not more complicated than the model allows, translate that intent into privileges the server supports.
Thus, standard ACL clients can still use the server with this limited set of privileges. The simple permission model maps clearly onto the standard WebDAV ACL privilege set, and this mapping can be explained by showing how concrete privileges encompass abstract privileges.
Because this mechanism for defining privileges allows so much flexibility for server implementation, there is added risk that interoperability will suffer. Client implementors may decide that the privilege model hierarchy is too complicated to parse and understand. We'll see how it plays out as client implementations develop and mature. 13.2.7 Finding Current User's PermissionsTypically, users are not allowed to read the entire ACL for a resource owned by somebody else. Sometimes this is a security precaution to limit users from finding out who they would have to impersonate to gain more access. Still, it would be pretty convenient for the client software to see what privileges are granted before attempting operations. A smart client wouldn't attempt operations known to be forbidden. In fact, a smart client would not even present those operations to the user. (Typically in GUI clients, operations that are forbidden are shown gray and are unclickable, to prevent the user from attempting an operation that will fail.) It's easy to resolve this dilemma, because there is no security concern if the client can find out what the current authenticated user is allowed to do. (The client could find this out anyway through trial and error.) The current-user-privilege-set property contains this information, in the form of a list of privileges granted. This property must be supported on any resource that supports ACLs (see Listing 13-4). Listing 13-4 Example value for current-user-privilege-set property.<D:current-user-privilege-set> <D:privilege> <D:read/> <D:write/> </D:privilege> </D:current-user-privilege-set>
Servers supporting ACLs should return this property with a value even when it's requested by an unauthenticated user. Thus, if the user is unauthenticated and the resource is publicly readable, the privilege set would include read. |