The holy grail: Single Signon RT with Windows Server, Active Directory and Apache 1.3 on unix

 

A lot of people use RT to track helpdesk requests, problem reports and other incident data at their jobs. An even larger number of people use or are forced to use Microsoft Active Directory as the central repository of username and password information at their jobs. As a result, probably the single most-asked question on the rt-users mailing list is "how do I unify logins between RT and ActiveDirectory?" Following close on behind that is "how do I get RT to use Windows authentication so people don't have to type in their password twice?" Strangely, these are questions that seemed to lack any authoritative answers.

Until now.

 

The tools

The steps

  1. Build and install a stock RT 3.4.4 and Apache 1.3.33

  2. Build and install mod_ntlm

  3. Create a Windows user called "LDAP User" for the RT ldap hooks to bind as. I recommend creating a "Role Accounts" security group and putting "LDAP User" into the "Role Accounts" group and removing it from the "Domain Users" group.

  4. Create at least one RT user with the same name as an ADS user and give that user superuser privs; otherwise, you'll keep having to switch ldap off on and off again. Alternatively, create a Windows user called "root".

  5. At a minimum, give the "Everyone" RT group the ability to create tickets. Additional ACLs as appropriate for your site's needs and policies.

  6. Configure RT for external web authentication. In RT_SiteConfig.pm:
    Set($WebExternalAuth , '1');
    Set($WebFallbackToInternalAuth , '1');
    Set($WebExternalGecos , undef);
    Set($WebExternalAuto , '1');

  7. Configure the apache virtual host to use mod_ntlm for authentication:
    <VirtualHost *>
       ServerName rt.example.com
       DocumentRoot /opt/rt3
       AddHandler fastcgi-script fcgi
       Alias /NoAuth/Images/ /opt/rt3/share/html/NoAuth/images/
       ScriptAlias / /opt/rt3/bin/mason_handler.fcgi/
       <Directory "/opt/rt3">
            AddDefaultCharset UTF-8
            SetHandler fastcgi-script
    
            AuthName "Request Tracker"
            AuthType NTLM
            NTLMAuth on
            NTLMAuthoritative on
            NTLMDomain DOMAINNAME
            NTLMServer pdc
            NTLMBackup bdc
            require valid-user
       </Directory>
    
       <Location /REST/1.0/NoAuth>
            satisfy any
            allow from all
       </Location>
       <Location /NoAuth>
            satisfy any
            allow from all
       </Location>
       <Location /NoAuth/images>
            SetHandler default-handler
       </Location>
    
    </VirtualHost>

  8. Install User_Local.pm from http://www.usit.uio.no/it/rt/modifications/ in /opt/rt3/lib/RT/.

  9. Edit /opt/rt3/lib/RT/User_Local.pm to fix a small logic error in UIO's code. At line 374, get rid of the extraneous "defined" test and the erroneous "!=" test, so that the line reads:
    if ($RT::LdapUser) {

  10. Install MailFrom_Local.pm from http://www.usit.uio.no/it/rt/modifications/ in /opt/rt3/lib/RT/Interface/Email/Auth.

  11. Add the local RT configuration for LDAP. In RT_SiteConfig.pm:
    Set($LDAPExternalAuth,		'1'); # Enable LDAP auth
    Set($LdapServer,		"ldapserver.example.com");
    Set($LdapCAFile,		undef);
    Set($LdapUser,			'cn=LDAP User,CN=Users,dc=example,dc=com'); 
    Set($LdapPass,			'password');
    Set($LdapAuthStartTLS,		'1'); # Need to use TLS or ldaps to check passwords
    Set($LdapAuthBase, 		"cn=Users,dc=example,dc=com");
    Set($LdapAuthUidAttr,		'sAMAccountName');
    Set($LdapAuthFilter,		'(objectClass=user)');
    Set($LdapMailBase,		'cn=Users,dc=example,dc=com');
    Set($LdapMailFilter,		'(objectClass=user)');
    Set($LdapMailScope,		'sub');
    Set($LdapMailSearchAttr,	'mail');
    %RT::LdapMailResultMap = (
            'sAMAccountName'        => 'Name',
            'mail'                  => 'EmailAddress',
            'cn'                    => 'RealName',
            ); 

  12. Install Web_Local.pm from http://blank.org/memory/work/Web_Local.pm in /opt/rt3/lib/RT/Interface.

  13. Restart apache

  14. Add the URL of your RT apache vhost to either the "trusted sites" or "intranet sites" zone of Internet Explorer. You can do this on a site-wide basis via the Group Policy Object for your domain controller:
    1. Run "MMC" from Start->Run
    2. From the "Console" menu, select "Add/Remove Snap-in"
    3. From the "Add/Remove Snap-in" dialog, hit the "Add" button.
    4. Select "Group Policy" and hit "Add". This will bring up the "Select Group Policy" wizard.
    5. Hit the "Browse..." button, then select the Default Domain Policy for your domain and hit OK.
    6. Hit the "Finish" button in the Select Group Policy wizard, then the "Close" button on the "Add Standalone Snap-in" dialog, then the "OK" button of the "Add/Remove Snap-in" dialog.
    7. From the Default Domain Policy root, browse down to: User Configuration -> Windows Settings -> Internet Explorer Maintenence -> Security, and double-click on the "Security Zones and Content Ratings" object.
    8. From the "Security Zones and Content Settings" tab, select the "Import the current security zones and privacy settings" radio button and click the "Modify Settings" button.
    9. This will bring up the GPO version of the "Internet Properties" control panel. Select either the "Local Intranet" or "Trusted Sites" zone as appropriate for your organization and hit the "Sites" button in order to add your RT vhost to that zone. If your RT vhost is not SSL-secured, you will need to un-check the "Require server verification" checkbox before adding the site.
      adding a domain to trusted sites
    10. Hit "OK" to close the "Internet Properties" panel, and then "OK" to close the "Security Zones and Content Ratings" panel. You can then close the entire MMC console.
    11. Your end-users may need to reboot for the Group Policy to be applied to them.

What the hell did I just do?

You've just made two major changes to the way RT operates:

  1. Access to the web interface of RT is now authenticated by apache, using mod_ntlm to verify passwords against Active Directory. If the account does not exist in RT, it is automatically created as an unprivileged user and therefore is directed to the SelfService interface. Because Internet Explorer sends NTLM authentication tokens to any site in the "Trusted" or "Intranet" zones, users do not even have to type their password: successfully logging into the windows domain is sufficient.

  2. Incoming email to rt-mailgate is checked against the LDAP server to see if the address is known there. If it is, the mail is treated as if it came from the Windows account that has that email address. If the account does not exist in RT, it is automatically created as an unprivileged user.

The upshot of all of this is that other than the creation of the initial superuser account, all RT accounts are created on-the-fly the first time a user interacts with RT, and RT usernames and passwords will always be the same as Windows usernames and passwords.


Notes