I.    Installation

      sudo apxs -ci mod_authz_svndb.c

      NOTE: the module is functional, but you should consider it experimental.
      Some configurations may or may not have the desired effect.  Be sure
      to test if your configuration works as intended.

      You also need to create a database in which to store the access rules.
      At the time of this writing, mod_authz_svndb only supports postgres.
      You can use any name and access settings you like for the database, as
      long as apache's mod_dbd can access it.  The tables within the database
      must be defined as specified in the included svndb.sql file.  A sample
      script containing the commands necessary to create the database in
      Fedora Linux is supplied.  If you are not using Fedora or Postgres or
      have a non-default installation of these products, you may need to
      modify the commands to suit your installation.

II.   Configuration

   1. Configuring Apache

      You will need to configure apache with a section like the following
      (Your settings will vary depending on the choices you made in step one).
      Don't forget to reload httpd after making your changes!

         LoadModule dav_svn_module modules/mod_dav_svn.so
         LoadModule dbd_module modules/mod_dbd.so
         LoadModule authz_svndb_module modules/mod_authz_svndb.so
         
         DBDriver pgsql
         DBDParams "dbname=svndb user=svn"
         
         DBDMin 1
         DBDKeep 32
         DBDMax 128
         DBDExptime 60
         
         <Location /subversion>
            DAV svn
         
            SVNAutoversioning on
            SVNPath /path/to/repos
         
            SSLRequireSSL
         
            AuthType Basic
            AuthBasicProvider ldap
            AuthLDAPURL <your ldap url>
            AuthName "YOUR AUTH NAME"
         
            AuthzSVNDBAuthoritative on
            AuthzSVNDBAccess "+r"
         
            require valid-user
         </Location>

      There are several ways to setup access checking for your subversion
      location.  Here are some simple examples.

      NOTE: AuthzSVNDBAuthoritative defaults to on and AuthzSVNDBAccess
      defaults to "+r"

      A. Example 1: Full anonymous access

         This configuration will allow full read and write access to
         everything under the root by anonymous users (The "none"
         disables access checking altogether).

         <Location /svn>
           DAV svn
           SVNPath /path/to/repos

           AuthzSVNDBAccess "none"
         </Location>

      B. Example 2: Authenticated access

         This configuration will check in the specified database and grant
         access to anyone who has a minimum access level of read (+r).  The
         AuthzSVNDBAccess setting specifies the minimum access requirements
         for the location that it is in.  These requirements can be over-
         ridden at lower levels in the repository with subsequent <Location>
         directives (See Feature 1).  If anonymous access is granted on this
         location in the database, the user will not be prompted for a
         password.

            LoadModule dav_svn_module modules/mod_dav_svn.so
            LoadModule dbd_module modules/mod_dbd.so
            LoadModule authz_svndb_module modules/mod_authz_svndb.so
            
            DBDriver pgsql
            DBDParams "dbname=svndb user=svn"
            
            DBDMin 1
            DBDKeep 32
            DBDMax 128
            DBDExptime 60

            <Location /svn>
              DAV svn
              SVNPath /path/to/repos

              AuthType Basic
              AuthName "Subversion repository"
              AuthUserFile /path/to/htpasswd/file

              AuthzSVNDBAccess "+r"

              Require valid-user
            </Location>

      C. Feature 1: Changing security requirements

         Supposing we had the configuration given in Example 2, and we wanted
         to grant anonymous users the ability to browse (read) our repository
         up to a certain path depth in our repository but we wanted to require
         authentication beyond that path depth.  One way we could accomplish
         this is to use the access level override feature of mod_authz_svndb.
         As is shown below, we could use the <Location> directives regular
         expression matching power to specify that all paths beyond a certain
         depth require read and write previledges to be accessed.  We would
         then grant anonymous users read access at the root of our repository.
         Since read and write access is required beyond a path depth of three,
         once the user tried to access a path beyond that point, they would be
         prompted for authentication.

         <Location ~ "^/svn/([^/]+/){3}">
           AuthzSVNDBAccess "+rw"
         </Location>

         You can continue changing your requirements on down the path.  The
         deapest matching path will always be the one that applies to a given
         request.

         You can prefix a minus to a permission (e.g., "-w") to deny the
         permission ("-rw denies all access regaurdless of the rules in
         the database" (May be useful in an emergency)).

   2. Specifying permissions

      This authentication module uses a database to store its security set-
      tings.  This has several advantages including the ability to change
      the permissions at any time without requiring a restart of the web
      server and the ability to deligate out access control to other users
      (either by granting them remote access to the database itself or by
      implementing your own simple web interface through which they can
      modify table values).

      The database contains two simple tables, one for storing groups and the
      other for setting permissions.

      The permissions table is named svnauthz and has the following columns:

         regex char(1): {t|f} defaults to f
         repository varchar(64): {null|<repository name>}
         path varchar(512): {null|<path>}
         entity varchar(256): {null|@<group>|<regex segment(s)>|username}
         access int: {0|1|2} default to 0

      The groups table is named svngroups and has the following columns:

         svngroup varchar(64)
         svnmember varchar(256)

      If regex is set to the character 't' then the repository and path
      columns are treated as regular expressions which must match the uri
      being requested to apply.

      Null values mean that this rule applies to all repositories/paths/
      entities (in the case of the entity field, this matches the anonymous
      user).

      The access field's values of 0, 1, and 2 correspond to none, read, and
      read-write respectively where none means that all requests matching this
      rule will be denied.

      When multiples rules match a request, they are ranked by scope with the
      narrowest scoped rule winning.  A rule that specifies a repository
      always beats one that does not.  The matching rule with the deapest path
      wins over all shallower ones.  Rules that match groups beat those that
      match anonymous and rules that match specific users beat rules that
      match groups.  And finally, all other things being equal, deny beats
      allow.

      The trailing slash on a non-regex path has special meaning.  It means
      that this rule is to apply to the directory and everything below it.
      Without the trailing slash, the rule only matches the one directory and
      does not apply to any below it.  Since a rule that matches a single
      directory is more specific in scope than one that matches an entire tree,
      the former will take priority over the latter when both are applicable.

      Anonymous access, once granted, must be explicitly revoked at a more
      specific scope for authenticated access to take effect.

      If regular expressions are being used and the path regex contains one or
      more matched substrings (match patterns bounded in parenthesis), the
      entity field can reference these matches by their index (e.g. $1, $2,
      etc).  For example, if the path field were set to ^/svn/homedirs/([^/]+)/
      you could use $1 in the entity field to require that the user and folder
      names match.  Another example would be if you had a path in your
      repository like /class/cs/101/001 and had a group named cs108-001 defined
      in the svngroups table, you could use path and entity patterns like
      ^/svn/class/([^/]+/)/([^/]+/)/([^/]+/)/ and @$1$2-$3 respectively to
      grant access to folders based on groups.

