Sophie

Sophie

distrib > Mageia > 3 > i586 > media > core-updates > by-pkgid > 1d6e0a3784534d5165fa22faeeca008d > files > 213

subversion-doc-1.7.10-1.1.mga3.i586.rpm

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Path-Based Authorization</title>
    <link rel="stylesheet" type="text/css" href="styles.css" />
    <meta name="generator" content="DocBook XSL Stylesheets V1.76.1" />
    <link rel="home" href="index.html" title="Version Control with Subversion" />
    <link rel="up" href="svn.serverconfig.html" title="Chapter 6. Server Configuration" />
    <link rel="prev" href="svn.serverconfig.httpd.html" title="httpd, the Apache HTTP Server" />
    <link rel="next" href="svn.serverconfig.operational-logging.html" title="High-level Logging" />
  </head>
  <body>
    <div class="navheader">
      <table width="100%" summary="Navigation header">
        <tr>
          <th colspan="3" align="center">Path-Based Authorization</th>
        </tr>
        <tr>
          <td width="20%" align="left"><a accesskey="p" href="svn.serverconfig.httpd.html">Prev</a> </td>
          <th width="60%" align="center">Chapter 6. Server Configuration</th>
          <td width="20%" align="right"> <a accesskey="n" href="svn.serverconfig.operational-logging.html">Next</a></td>
        </tr>
      </table>
      <hr />
    </div>
    <div class="sect1" title="Path-Based Authorization">
      <div class="titlepage">
        <div>
          <div>
            <h2 class="title" style="clear: both"><a id="svn.serverconfig.pathbasedauthz"></a>Path-Based Authorization</h2>
          </div>
        </div>
      </div>
      <p>Both Apache and <span class="command"><strong>svnserve</strong></span> are capable of
      granting (or denying) permissions to users.  Typically this is
      done over the entire repository: a user can read the repository
      (or not), and she can write to the repository (or not).  It's
      also possible, however, to define finer-grained access rules.
      One set of users may have permission to write to a certain
      directory in the repository, but not others; another directory
      might not even be readable by all but a few special
      people.  As files are paths, too, it's even possible to restrict
      access on a per file basis.</p>
      <p>Both servers use a common file format to describe these
      path-based access rules.  In the case of Apache, one needs to
      load the <span class="command"><strong>mod_authz_svn</strong></span> module and then add
      the <code class="literal">AuthzSVNAccessFile</code> directive (within
      the <code class="filename">httpd.conf</code> file) pointing to your own
      access rules file.  (For a full explanation, see
      <a class="xref" href="svn.serverconfig.httpd.html#svn.serverconfig.httpd.authz.perdir" title="Per-directory access control">the section called “Per-directory access control”</a>.)  If
      you're using <span class="command"><strong>svnserve</strong></span>, you need to make
      the <code class="literal">authz-db</code> variable
      (within <code class="filename">svnserve.conf</code>) point to your access
      rules file.</p>
      <div class="sidebar" title="Do You Really Need Path-Based Access Control?">
        <div class="titlepage">
          <div>
            <div>
              <p class="title">
                <strong>Do You Really Need Path-Based Access Control?</strong>
              </p>
            </div>
          </div>
        </div>
        <p>A lot of administrators setting up Subversion for the
        first time tend to jump into path-based access control without
        giving it a lot of thought.  The administrator usually knows
        which teams of people are working on which projects, so it's
        easy to jump in and grant certain teams access to certain
        directories and not others.  It seems like a natural thing,
        and it appeases the administrator's desire to maintain tight
        control of the repository.</p>
        <p>Note, though, that there are often invisible (and
        visible!) costs associated with this feature.  In the visible
        category, the server needs to do a lot more work to ensure
        that the user has the right to read or write each specific
        path; in certain situations, there's very noticeable
        performance loss.  In the invisible category, consider the
        culture you're creating.  Most of the time, while certain
        users <span class="emphasis"><em>shouldn't</em></span> be committing changes to
        certain parts of the repository, that social contract doesn't
        need to be technologically enforced.  Teams can sometimes
        spontaneously collaborate with each other; someone may want to
        help someone else out by committing to an area she doesn't
        normally work on.  By preventing this sort of thing at the
        server level, you're setting up barriers to unexpected
        collaboration.  You're also creating a bunch of rules that
        need to be maintained as projects develop, new users are
        added, and so on.  It's a bunch of extra work to
        maintain.</p>
        <p>Remember that this is a version control system!  Even if
        somebody accidentally commits a change to something she
        shouldn't, it's easy to undo the change.  And if a user
        commits to the wrong place with deliberate malice, it's a
        social problem anyway, and that the problem needs to be dealt
        with outside Subversion.</p>
        <p>So, before you begin restricting users' access rights, ask
        yourself whether there's a real, honest need for this, or
        whether it's just something that <span class="quote">“<span class="quote">sounds good</span>”</span> to
        an administrator.  Decide whether it's worth sacrificing some
        server speed, and remember that there's very little risk
        involved; it's bad to become dependent on technology as a
        crutch for social problems.<sup>[<a id="idp15246320" href="#ftn.idp15246320" class="footnote">61</a>]</sup></p>
        <p>As an example to ponder, consider that the Subversion
        project itself has always had a notion of who is allowed to
        commit where, but it's always been enforced socially.  This is
        a good model of community trust, especially for open source
        projects.  Of course, sometimes there <span class="emphasis"><em>are</em></span>
        truly legitimate needs for path-based access control; within
        corporations, for example, certain types of data really can be
        sensitive, and access needs to be genuinely restricted to
        small groups of people.</p>
      </div>
      <p>Once your server knows where to find your access file, it's
      time to define the rules.</p>
      <p>The syntax of the file is the same familiar one used
      by <code class="filename">svnserve.conf</code> and the runtime
      configuration files.  Lines that start with a hash
      (<code class="literal">#</code>) are ignored.  In its simplest form, each
      section names a repository and path within it, as well as the
      authenticated usernames are the option names within each
      section.  The value of each option describes the user's level of
      access to the repository path: either
      <code class="literal">r</code> (read-only) or <code class="literal">rw</code>
      (read/write).  If the user is not mentioned at all, no access is
      allowed.</p>
      <p>To be more specific: the value of the section names is
      either of the form <code class="literal">[repos-name:path]</code> or of the
      form <code class="literal">[path]</code>.</p>
      <div class="warning" title="Warning" style="margin-left: 0.5in; margin-right: 0.5in;">
        <table border="0" summary="Warning">
          <tr>
            <td rowspan="2" align="center" valign="top" width="25">
              <img alt="[Warning]" src="images/warning.png" />
            </td>
            <th align="left">Warning</th>
          </tr>
          <tr>
            <td align="left" valign="top">
              <p>Prior to version 1.7, Subversion treated repository names
        and paths in a case-insensitive fashion for the purposes of
        access control, converting them to lower case internally
        before comparing them against the contents of your access
        file.  It now does these comparisons case-sensitively.  If you
        upgraded to Subversion 1.7 from an older version, you should
        review your access files for case correctness.</p>
            </td>
          </tr>
        </table>
      </div>
      <p>If you're using the
      <code class="literal">SVNParentPath</code> directive, it's important
      to specify the repository names in your sections.  If you omit
      them, a section such as
      <code class="literal">[/some/dir]</code> will match the path
      <code class="filename">/some/dir</code> in <span class="emphasis"><em>every</em></span>
      repository.  If you're using the <code class="literal">SVNPath</code>
      directive, however, it's fine to only define paths in your
      sections—after all, there's only one repository.</p>
      <div class="informalexample">
        <pre class="programlisting">
[calc:/branches/calc/bug-142]
harry = rw
sally = r
</pre>
      </div>
      <p>In this first example, the user <code class="literal">harry</code> has
      full read and write access on the
      <code class="filename">/branches/calc/bug-142</code> directory in the
      <code class="literal">calc</code> repository, but the user
      <code class="literal">sally</code> has read-only access.  Any other users
      are blocked from accessing this directory.</p>
      <div class="warning" title="Warning" style="margin-left: 0.5in; margin-right: 0.5in;">
        <table border="0" summary="Warning">
          <tr>
            <td rowspan="2" align="center" valign="top" width="25">
              <img alt="[Warning]" src="images/warning.png" />
            </td>
            <th align="left">Warning</th>
          </tr>
          <tr>
            <td align="left" valign="top">
              <p><span class="command"><strong>mod_dav_svn</strong></span> offers a directive,
        <code class="literal">SVNReposName</code>, which allows administrators
        to define a more human-friendly name, of sorts, for a
        repository:</p>
              <div class="informalexample">
                <pre class="programlisting">
&lt;Location /svn/calc&gt;
  SVNPath /var/svn/calc
  SVNReposName "Calculator Application"
…
</pre>
              </div>
              <p>This allows <span class="command"><strong>mod_dav_svn</strong></span> to identify the
        repository by something other than merely its server directory
        basename—<code class="filename">calc</code>, in the previous
        example—when providing directory listings of repository
        content.  Be aware, however, that when consulting the access
        file for authorization rules, Subversion uses this repository
        basename for comparison, <span class="emphasis"><em>not</em></span> any
        configured human-friendly name.</p>
            </td>
          </tr>
        </table>
      </div>
      <p>Of course, permissions are inherited from parent to child
      directory.  That means we can specify a subdirectory with a
      different access policy for Sally:</p>
      <div class="informalexample">
        <pre class="programlisting">
[calc:/branches/calc/bug-142]
harry = rw
sally = r

# give sally write access only to the 'testing' subdir
[calc:/branches/calc/bug-142/testing]
sally = rw
</pre>
      </div>
      <p>Now Sally can write to the <code class="filename">testing</code>
      subdirectory of the branch, but can still only read other parts.
      Harry, meanwhile, continues to have complete read/write access
      to the whole branch.</p>
      <p>It's also possible to explicitly deny permission to someone
      via inheritance rules, by setting the username variable to
      nothing:</p>
      <div class="informalexample">
        <pre class="programlisting">
[calc:/branches/calc/bug-142]
harry = rw
sally = r

[calc:/branches/calc/bug-142/secret]
harry =
</pre>
      </div>
      <p>In this example, Harry has read/write access to the
      entire <code class="filename">bug-142</code> tree, but has absolutely no
      access at all to the <code class="filename">secret</code> subdirectory
      within it.</p>
      <div class="tip" title="Tip" style="margin-left: 0.5in; margin-right: 0.5in;">
        <table border="0" summary="Tip">
          <tr>
            <td rowspan="2" align="center" valign="top" width="25">
              <img alt="[Tip]" src="images/tip.png" />
            </td>
            <th align="left">Tip</th>
          </tr>
          <tr>
            <td align="left" valign="top">
              <p>The thing to remember is that the most specific path
        always matches first.  The server tries to match the path
        itself, and then the parent of the path, then the parent of
        that, and so on.  The net effect is that mentioning a specific
        path in the access file will always override any permissions
        inherited from parent directories.</p>
            </td>
          </tr>
        </table>
      </div>
      <p>By default, nobody has any access to the repository at all.
      That means that if you're starting with an empty file, you'll
      probably want to give at least read permission to all users at
      the root of the repository.  You can do this by using the
      asterisk variable (<code class="literal">*</code>), which means <span class="quote">“<span class="quote">all
      users</span>”</span>:</p>
      <div class="informalexample">
        <pre class="programlisting">
[/]
* = r
</pre>
      </div>
      <p>This is a common setup; notice that no repository
      name is mentioned in the section name.  This makes all repositories
      world-readable to all users.  Once all users have read access to
      the repositories, you can give explicit
      <code class="literal">rw</code> permission to certain users on specific
      subdirectories within specific repositories.</p>
      <p>The access file also allows you to define whole groups of
      users, much like the Unix <code class="filename">/etc/group</code>
      file:</p>
      <div class="informalexample">
        <pre class="programlisting">
[groups]
calc-developers = harry, sally, joe
paint-developers = frank, sally, jane
everyone = harry, sally, joe, frank, jane
</pre>
      </div>
      <p>Groups can be granted access control just like users.
      Distinguish them with an <span class="quote">“<span class="quote">at</span>”</span>
      (<code class="literal">@</code>) prefix:</p>
      <div class="informalexample">
        <pre class="programlisting">
[calc:/projects/calc]
@calc-developers = rw

[paint:/projects/paint]
jane = r
@paint-developers = rw
</pre>
      </div>
      <p>Another important fact is that group permissions are not
      overridden by individual user permissions. Rather, the
      <span class="emphasis"><em>combination</em></span> of all matching permissions is
      granted.  In the prior example, Jane is a member of the
      <code class="literal">paint-developers</code> group, which has read/write
      access.  Combined with the <code class="literal">jane = r</code> rule,
      this still gives Jane read/write access.  Permissions for group
      members can only be extended beyond the permissions the group
      already has. Restricting users who are part of a group to less
      than their group's permissions is impossible.</p>
      <p>Groups can also be defined to contain other groups:</p>
      <div class="informalexample">
        <pre class="programlisting">
[groups]
calc-developers = harry, sally, joe
paint-developers = frank, sally, jane
everyone = @calc-developers, @paint-developers
</pre>
      </div>
      <p>Subversion 1.5 brought several useful features to the access
      file syntax—username aliases, authentication class tokens,
      and a new rule exclusion mechanism—all of which further
      simplify the maintenance of the access file.  We'll describe
      first the username aliases feature.</p>
      <p>Some authentication systems expect and carry relatively
      short usernames of the sorts we've been describing
      here—<code class="literal">harry</code>,
      <code class="literal">sally</code>, <code class="literal">joe</code>, and so on.  But
      other authentication systems—such as those which use LDAP
      stores or SSL client certificates—may carry much more
      complex usernames.  For example, Harry's username in an
      LDAP-protected system might be <code class="literal">CN=Harold
      Hacker,OU=Engineers,DC=red-bean,DC=com</code>.  With
      usernames like that, the access file can become quite bloated
      with long or obscure usernames that are easy to mistype.
      Fortunately, username aliases allow you to have to type the
      correct complex username only once, in a statement which assigns to
      it a more easily digestable alias.</p>
      <div class="informalexample">
        <pre class="programlisting">
[aliases]
harry = CN=Harold Hacker,OU=Engineers,DC=red-bean,DC=com
sally = CN=Sally Swatterbug,OU=Engineers,DC=red-bean,DC=com
joe = CN=Gerald I. Joseph,OU=Engineers,DC=red-bean,DC=com
…
</pre>
      </div>
      <p>Once you've defined a set of aliases, you can refer to the
      users elsewhere in the access file via their aliases in all the
      same places you could have instead used their actual usernames.
      Simply prepend an ampersand to the alias to distinguish it from
      a regular username:</p>
      <div class="informalexample">
        <pre class="programlisting">
[groups]
calc-developers = &amp;harry, &amp;sally, &amp;joe
paint-developers = &amp;frank, &amp;sally, &amp;jane
everyone = @calc-developers, @paint-developers
</pre>
      </div>
      <p>You might also choose to use aliases if your users'
      usernames change frequently.  Doing so allows you to need to
      update only the aliases table when these username changes occur,
      instead of doing global-search-and-replace operations on the
      whole access file.</p>
      <p>Subversion also supports some <span class="quote">“<span class="quote">magic</span>”</span> tokens
      for helping you to make rule assignments based on the user's
      authentication class.  One such token is
      the <code class="literal">$authenticated</code> token.  Use this token
      where you would otherwise specify a username, alias, or group
      name in your authorization rules to declare the permissions
      granted to any user who has authenticated with any username at
      all.  Similarly employed is the <code class="literal">$anonymous</code>
      token, except that it matches everyone who has
      <span class="emphasis"><em>not</em></span> authenticated with a username.</p>
      <div class="informalexample">
        <pre class="programlisting">
[calendar:/projects/calendar]
$anonymous = r
$authenticated = rw
</pre>
      </div>
      <p>Finally, another handy bit of access file syntax magic is
      the use of the tilde (<code class="literal">~</code>) character as an
      exclusion marker.  In your authorization rules, prefixing a
      username, alias, group name, or authentication class token with
      a tilde character will cause Subversion to apply the rule to
      users who do <span class="emphasis"><em>not</em></span> match the rule.  Though
      somewhat unnecessarily obfuscated, the following block is
      equivalent to the one in the previous example:</p>
      <div class="informalexample">
        <pre class="programlisting">
[calendar:/projects/calendar]
~$authenticated = r
~$anonymous = rw
</pre>
      </div>
      <p>A less obvious example might be as follows:</p>
      <div class="informalexample">
        <pre class="programlisting">
[groups]
calc-developers = &amp;harry, &amp;sally, &amp;joe
calc-owners = &amp;hewlett, &amp;packard
calc = @calc-developers, @calc-owners

# Any calc participant has read-write access...
[calc:/projects/calc]
@calc = rw

# ...but only allow the owners to make and modify release tags.
[calc:/projects/calc/tags]
~@calc-owners = r
</pre>
      </div>
      <p>All of the above examples use directories, because defining
      access rules on them is the most common case.  But is similarly
      able to restrict access on file paths, too.</p>
      <div class="informalexample">
        <pre class="programlisting">
[calendar:/projects/calendar/manager.ics]
harry = rw
sally = r
</pre>
      </div>
      <div class="sidebar" title="Partial Readability and Checkouts">
        <div class="titlepage">
          <div>
            <div>
              <p class="title">
                <strong>Partial Readability and Checkouts</strong>
              </p>
            </div>
          </div>
        </div>
        <p>If you're using Apache as your Subversion server and have
        made certain subdirectories of your repository unreadable to
        certain users, you need to be aware of a possible nonoptimal
        behavior with <span class="command"><strong>svn checkout</strong></span>.</p>
        <p>When the client requests a checkout or update over HTTP,
        it makes a single server request and receives a single (often
        large) server response.  When the server receives the request,
        that is the <span class="emphasis"><em>only</em></span> opportunity Apache has
        to demand user authentication.  This has some odd side
        effects.  For example, if a certain subdirectory of the
        repository is readable only by user Sally, and user Harry
        checks out a parent directory, his client will respond to the
        initial authentication challenge as Harry.  As the server
        generates the large response, there's no way it can resend an
        authentication challenge when it reaches the special
        subdirectory; thus the subdirectory is skipped altogether,
        rather than asking the user to reauthenticate as Sally at the
        right moment.  In a similar way, if the root of the repository
        is anonymously world-readable, the entire checkout will be
        done without authentication—again, skipping the
        unreadable directory, rather than asking for authentication
        partway through.</p>
      </div>
      <div class="footnotes">
        <br />
        <hr width="100" align="left" />
        <div class="footnote">
          <p><sup>[<a id="ftn.idp15246320" href="#idp15246320" class="para">61</a>] </sup>A common theme in
        this book!</p>
        </div>
      </div>
    </div>
    <div class="navfooter">
      <hr />
      <table width="100%" summary="Navigation footer">
        <tr>
          <td width="40%" align="left"><a accesskey="p" href="svn.serverconfig.httpd.html">Prev</a> </td>
          <td width="20%" align="center">
            <a accesskey="u" href="svn.serverconfig.html">Up</a>
          </td>
          <td width="40%" align="right"> <a accesskey="n" href="svn.serverconfig.operational-logging.html">Next</a></td>
        </tr>
        <tr>
          <td width="40%" align="left" valign="top">httpd, the Apache HTTP Server </td>
          <td width="20%" align="center">
            <a accesskey="h" href="index.html">Home</a>
          </td>
          <td width="40%" align="right" valign="top"> High-level Logging</td>
        </tr>
      </table>
    </div>
    <div xmlns="" id="svn-footer">
      <hr />
      <p>You are reading <em>Version Control with Subversion</em> (for Subversion 1.7), by Ben Collins-Sussman, Brian W. Fitzpatrick, and C. Michael Pilato.<br />
       This work is licensed under the <a href="http://creativecommons.org/licenses/by/2.0/">Creative Commons Attribution License v2.0</a>.<br />
       To submit comments, corrections, or other contributions to the text, please visit <a href="http://www.svnbook.com/">http://www.svnbook.com/</a>.</p>
    </div>
  </body>
</html>