CollabNet
Submerged - CollabNet's Subversion Blog
CollabNet Community

Categories

  • Administration (7)
  • Client Tools (13)
  • downloads (2)
  • General (36)
  • Non-Developers (2)
  • Subversion Client (32)
  • Subversion Events (4)
  • Subversion in the Enterprise (24)
  • Subversion Server (19)
  • Web/Tech (1)

Past 6 Months

  • July 2009 (2)
  • June 2009 (2)
  • May 2009 (5)
  • April 2009 (2)
  • March 2009 (4)
  • February 2009 (2)

Archives

All Archives...
RSS Syndicate this blog

Authz and Anon Authn Agony

A recent first-time attempt at using Subversion's path-based authorization module turned out to be less trivial than I'd planned because I was trying to use it with a repository that allowed anonymous read access. Things went well at first — I did some copying and pasting of sample httpd.conf directives and authz file contents from Version Control with Subversion, tweaking as necessary to suit my needs. In a short time, I had what I thought was the perfect setup. I was wrong.

Say, like me, you wish to configure a repository such that it permits anonymous reads to most of it, authenticated reads to the rest of it, and authenticated writes to the whole thing. You already have an Apache htpasswd file with your writers' usernames and password hashes, and you've configured Apache to use that htpasswd file for authentication, and an authz file for authorization. You then make the obvious additions to your authz file:

[groups]
writers = someuser1, someuser2, …

[repository:/]
* = r
@writers = rw

[repository:/trunk/private-area]
* =
@writers = rw

There's a group with your writers' usernames. There's a rule which grants anonymous read to the world, and write access to just the writers. And there's an override rule which removes read access from unauthenticated users in the repository's private area. Looks great.

Then you start testing.

Upon checking out your repository's /trunk directory, anonymous users get what you'd expect — the tree, minus the /trunk/private-area directory.

But what about your authenticated would-be writers? Ah, therein lies the rub! There are no authenticated users. Since anonymous users can checkout the tree, Apache never bothers to query you for authentication credentials. And you can't force Subversion to transmit authentication credentials when Apache hasn't asked for them.

So what's the workaround?

First, you could disable anonymous access altogether, and force non-writers to share a username like "anonymous" and a publicized password. In your authz rules, the user "anonymous" would have only read permission, and only on the public portion of the repository. This works fine, but at some discomfort to non-writers. They now have to supply a password which, though not secret, might still be non-obvious and/or unknown to them.

Secondly, you could just leave things the way they are, and force writers to checkout just the private area of the repository separately. They won't have the luxury of both the public and private areas being connected inside a single working copy, but that might be okay.

Thirdly, you could keep the private stuff in its own repository. For writers, this is very similar to the second workaround. But your writers won't be able to make a private thing public without breaking the history across repositories.

Finally, you could setup a second <Location> block in your httpd.conf file which points to the same repository but with a slightly different URL (for example, with "-no-anon" appended to it). In this block, disallow anonymous access. Then add a matching redundant entry in your authz file, too:

[repository-no-anon:/]
* =
@writers = rw

Now, anonymous non-writers can checkout from the original repository URL without prompting, and won't see the private area. Non-anonymous writers can checkout from the alternate repository URL with prompting, and will see the private area.  (Thanks to Max Bowsher for this great hybrid workaround idea.)

C. Michael Pilato

About the Author

C. Michael (Mike) Pilato has been on the Subversion project as a committer since 2000. Mike is one of the co-authors of “Version Control with Subversion” and he is on the board of the non-profit Subversion Corporation.
Permalink
Categories: Subversion Server

TrackBack

TrackBack URL for this post: http://www.typepad.com/services/trackback/6a00d834515ac169e200d8352912a153ef

Comments

The Subversion book points out the correct way to handle this: you need to set

AuthzSVNAccessFile /path/to/repo/authz
Require valid-user
Satisfy Any

with your authentication options.

That way the client will first try the request unauthenticated, mod_authz_svn will refuse it based on your authz file, and so Apache will return 401 telling the client to retry with authentication. The client then prompts the user for a password, Apache gets the same request but with credentials, it is accepted by mod_authz_svn, and everyone is happy.

Dan C | July 27, 2007 at 08:43 AM

Thanks for your comment, Dan C. But as one of the co-authors of the book, I definitely checked there first before claiming defeat. :-)

My httpd.conf is actually configured exactly as you (and the book) recommend. The problem in my situation is that only a subdirectory of my repository is meant to be private. That would work fine if Subversion fetched each file and directory in the tree individually, with separate HTTP requests which could each be individually optionally authenticated. But Subversion uses a single large REPORT request/response for checkouts and updates and such.

Because the root of my repository is readable by all (per my authz rules), mod_authz_svn won't refuse it based on my authz file, and Apache won't return 401 telling the client to retry with authn. That means my one checkout REPORT request will succeed as an anonymous user. But Subversion will still internally verify that my anonymous user has access to each and every path under the checked-out tree, and because that user doesn't have access to the private portion of the tree, Subversion will simply omit that subtree from the checkout altogether.

C. Michael Pilato | July 27, 2007 at 09:49 AM

I can't seem to get your suggestion to work; my situation is only slightly different. I have 3 classes of users: anon, regular, and special. In my repository, I have a single folder (let's say "private") that should be rw only for special users, invisible to everyone else. Anon can read everything but private, and normal users have rw on everything but private.

I have added a new Location entry to httpd.conf, which is exactly the same as the original one except the name is slightly different.

I then add the perms as you suggest to dav_svn.authz:

[repo:/]
* = r
@regularusers = rw

[repo:/path/to/private]
* =

# Now spec the alternate url, such that only special users have rw on everything
[repo-special:/]
@specialusers = rw

---

When I attempt to checkout using the new url repo-special, I still get the "403 Forbidden" error as before.

Any ideas?

Thanks...thomas b

Thomas B | November 30, 2007 at 08:32 AM

I can't seem to get your suggestion to work; my situation is only slightly different. I have 3 classes of users: anon, regular, and special. In my repository, I have a single folder (let's say "private") that should be rw only for special users, invisible to everyone else. Anon can read everything but private, and normal users have rw on everything but private.

I have added a new Location entry to httpd.conf, which is exactly the same as the original one except the name is slightly different.

I then add the perms as you suggest to dav_svn.authz:

[repo:/]
* = r
@regularusers = rw

[repo:/path/to/private]
* =

# Now spec the alternate url, such that only special users have rw on everything
[repo-special:/]
@specialusers = rw

---

When I attempt to checkout using the new url repo-special, I still get the "403 Forbidden" error as before.

Any ideas?

Thanks...thomas b

Thomas B | November 30, 2007 at 08:34 AM

Thomas B, does your second httpd.conf Location block demand authentication for all accesses, like my post recommends? Is there a chance that in your testing Subversion is using a cache non-special user's credentials against that special repository?

C. Michael Pilato | November 30, 2007 at 09:57 AM

Thanks for the article, Michael!

It really saved me a lot of time and hair on my head!

Vladiuz | June 26, 2008 at 02:51 AM

Hi Michael,

Is it possible to make some folders invisible to certain users? For example, assuming I only have 2 folders, FolderA & FolderB in my repository. Currently, irregardless of the user's permissions, a "svn ls" would list both folders. Is there a way to prevent certain users from seeing the existence of FolderB?

Thanks in advance.

Cheers,
John

John | July 21, 2008 at 12:37 AM

@John: Sure! What would path-based authorization be if not a means by which to authorize access to paths? Take a cruise though the Path-Based Authorization section of Version Control with Subversion (http://svnbook.red-bean.com/nightly/en/svn.serverconfig.pathbasedauthz.html). Basically, you need two things in place: 1) authentication, so that Subversion always know what user is accessing what, and then 2) the authorization rules that say which paths a particular user can and cannot access, and whether that access is read-only or read-write. Now, this only works when using Subversion in client-server model (hosted via Apache/mod_dav_svn or svnserve), but that's the most common deployment scenario anyway, so hopefully it's yours, too.

C. Michael Pilato | July 21, 2008 at 06:50 AM

Hi Michael,

Thanks for the prompt reply. Sorry if I was not clear in my previous post but I have implemented Path-Based Authorization (on Apache) and implemented authentication as well. The issue really is that a user who does not have read access to a folder will still be able to see the existence of the folder. Is there a way to hide the folder such that if a user does not have read access to the folder, he will not be able to see the folder itself?

For example:

[repo:/]
* = r
@regularusers = rw

[repo:/Logs]
* =
@admin = rw

In the above example, all users would be able to "see" the Logs folder even though they are unable to access it. Is there a way to disallow @regularusers to see the existence of the Logs folder?

Thanks!:)

Cheers,
John

John | July 21, 2008 at 07:17 AM

@John: OH! Sorry, yes, I misunderstood the question. Unfortunately, no, that's not possible with Subversion today. It's been documented since the inception of Subversion's authz policy as a known leakage (see http://svn.collab.net/repos/svn/trunk/notes/authz_policy.txt).

C. Michael Pilato | July 21, 2008 at 07:38 AM

Hi Michael,

Thanks for pointing that out. :)

Cheers,
John

John | July 21, 2008 at 06:08 PM

Thank you so much for your post. It was extremely useful (saved my day).
-Patricia

Patricia Goldweic | July 28, 2008 at 03:21 PM

I have a related question. If I follow your suggested use of the extra tag in the Apache configuration file, it all works out fine in terms of checkout. However, when it is time to create tags for a project that has some private folders, it seems that I'll have to go through the pain of setting the authorization rules for each of these tags, since, although I am tagging the whole trunk, I don't want the private folders to be accessible by the general public in my new tags :-(.
Do you have any suggestion as to how to deal with this problem? Or, would you perhaps say that what you described as your third option in your post (that is: create a separate repository that holds your private folders) may actually be the most practical approach in this case?
-Patricia

Patricia Goldweic | July 29, 2008 at 01:24 PM

@Patricia: Subversion's authorization logic is path-based, not object-based like a real ACL system might be. So yes, when you change the path of a versioned object deemed private by authz rules (either via a rename, or by exposing the object at multiple paths due to a copy such as you'd use when branching and tagging), you must update the authz rules to account for the change. For this reason, I think it very unwise to mix public and private data in the same tree if that data is likely to be branched or tagged.

C. Michael Pilato | July 29, 2008 at 01:36 PM

Is it possible to use LDAP for authentication and still use SVN authz to restrict user access when using Apache as the server?

Michael Griffith | November 13, 2008 at 09:29 AM

@Michael: Sure. I've not personally managed such a configuration (so I can't help you with the details), but my understanding is that this is a very common setup in corporate environments.

C. Michael Pilato | November 13, 2008 at 10:02 AM

@Michael Griffith:

You can enable LDAP authentication as follows (in apache config):

---------------------------------------------------
DAV svn
SVNPath /var/lib/svn
AuthzSVNAccessFile /var/lib/svn/authz
AuthLDAPEnabled on
AuthLDAPUrl ldap://ldap.server:389/base-dn
AuthType basic
AuthName "Subversion Repository"
require valid-user
---------------------------------------------------

One problem here is that ldap groups are not used in the authz access checks.
I have written a patch to the authz module that uses the system groups (via getgrnam)
instead of the groups defined in the authz file under the [groups] section.
I.e. using libnss_ldap, you get the groups from ldap for access checks!

I plan to propose this for upstream subversion code soon.

Cheers - Michael

Michael Adam | December 05, 2008 at 02:24 PM

Oops, sorry, I found a working configuration where instead of "AuthLDAPEnabled on",
the following two options are set:

---------------------------------
AuthzLDAPAuthoritative on
AuthBasicProvider ldap
---------------------------------

I currently don't have a setup available to verify correct workings.
But I think this was the correct version.

Michael

Michael Adam | December 05, 2008 at 02:35 PM

Oops, sorry, I found a working configuration where instead of "AuthLDAPEnabled on",
the following two options are set:

---------------------------------
AuthzLDAPAuthoritative on
AuthBasicProvider ldap
---------------------------------

I currently don't have a setup available to verify correct workings.
But I think this was the correct version.

Michael

Michael Adam | December 05, 2008 at 02:41 PM

Post a comment

If you have a TypeKey or TypePad account, please Sign In

You are currently signed in as (nobody). Sign Out

  • ©2008 CollabNet Corporation
    • Site Feedback
    • Terms of Use
    • Privacy Policy
    • Copyright & Trademark