Recently I was setting up a Subversion repository (on a Linux server) that needs to be accessed via HTTP. Users should be able connect to the repositories without authentication, but authentication is needed to perform write actions. Of course Apache’s
htpasswd/htaccess combination would provide just that, but since we have a Windows 2008 Active Domain controller that provides authentication to our Windows machines I thought it would be a good idea to use it.
Configuration of the autentication and authorization is done by Apache’s mod_authnz_ldap and (on Red Hat EL) configured in
/etc/httpd/conf.d/subversion.conf (which exists after installing the subversion package with
Basic configuration with htaccess
For simple authentication with Apache’s htaccess mechanism the config looks like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
LoadModule dav_svn_module modules/mod_dav_svn.so LoadModule authz_svn_module modules/mod_authz_svn.so <Location /repos> DAV svn SVNParentPath /var/www/svn SVNReposName "My company's repository" # Limit write permission to list of valid users. <LimitExcept GET PROPFIND OPTIONS REPORT> AuthType Basic AuthName "Authorization Realm for SVN" AuthUserFile /etc/httpd/conf.d/svn_htpasswd Require valid-user </LimitExcept> </Location>
htpasswd to create a file with usernames and passwords on the server users could commit to the repository.
Configuration for AD Global Catalog
The first LDAP-like construction I got working was when using the AD Global Catalog. Normal LDAP traffic uses port 389, but the AD’s Global Catalog uses port 3268. The username needed to commit with SVN is
windows_logon_name@your_AD.suffix, the so-called
suffix are the DC’s of the LDAP/AD tree. By using this userPrincipalName users from different DC trees can be authenticated. The configuration file looks this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
LoadModule dav_svn_module modules/mod_dav_svn.so LoadModule authz_svn_module modules/mod_authz_svn.so <Location /repos> DAV svn SVNParentPath /var/www/svn SVNReposName "My company's repository" # Limit write permission to list of valid users. <LimitExcept GET PROPFIND OPTIONS REPORT> AuthType Basic AuthName "Authorization using your LDAP account" AuthBasicProvider ldap AuthzLDAPAuthoritative off # Active Directory requires an authenticating DN to access records AuthLDAPBindDN "svntest@your_AD.suffix" # This is the password for the AuthLDAPBindDN user in Active Directory AuthLDAPBindPassword "some_good_password" # The LDAP query URL AuthLDAPURL "ldap://ldap.your_company.com:3268/?userPrincipalName?sub" AuthUserFile /dev/null # Require a valid user Require valid-user </LimitExcept> </Location>
With this configuration I could commit with this command:
svn commit -m "First AD test" --username your_windows_username@your_AD.suffix.
Configuration for AD + Windows logon Name
As mentioned earlier, the previous method allows people from different parts of the AD tree to log in. In order to restrict access to for example a specific OU, the
AuthLDAPURL has to be changed. In our case the LDAP tree is not a simple
OU=Users,DC=our_company,DC=com, but consists of several nested OU structures. I used the
adsiedit.msc snapin (ADSI editor) on the AD controller to find out the exact structure, since I needed to find out which parts were CNs and which where OUs.
In order to authenticate against a the windows login names in a certain sub-OU the
AuthLDAPURL "ldap://ldap.your_company.com:389/OU=Group 1, OU=Location 1, DC=your_AD, DC=suffix?sAMAccountName?sub?(objectClass=*)"
Configuration for AD + Windows Display Name
If you want the users to use their common name (the Display Name in the AD) use:
AuthLDAPURL "ldap://ldap.your_company.com:389/OU=Group 1, OU=Location 1 DC=your_AD, DC=suffix?cn"
Users can now commit with:
svn commit -m "Another AD test" --username "Firstname Lastname".
Configuration for AD + another field
In our case login authentication on the Linux/UNIX machines is not done through the AD. Furthermore, the user names are not synchronised between Linux and Windows. This poses a small inconvenience, since by default an
svn commit uses the Linux username. As the AD doesn’t know about this name, the first authentication fails. subsequently Apache asks for the user name, and then the user can enter his Windows AD credentials (principle name, display name or windows login name, depending on which of the above configurations was chosen). So as a quick workaround (and just to see if I could get it to work) I entered my Linux user name into the Office field in the AD. In the ADSI Editor I found the real name of the field:
physicalDeliveryOfficeName With the following
AuthLDAPURL I could use the Office field to authenticate me:
AuthLDAPURL "ldap://ldap.your_company.com:389/OU=Group 1, OU=Location 1 DC=your_AD, DC=suffix?physicalDeliveryOfficeName"
Now a simple
svn commit works.
Some useful links:
- Documentation of mod_authnz_ldap
- A blog post where I learned the basics
- Another blog about SVN + AD, with a good commented example