9.3.  Authenticating users against Windows Active Directory

This section describes how to integrate ThinLinc in an Active Directory (AD) environment. This allows existing users to authenticate and use ThinLinc, logging in using the same credentials they use to login to fat Windows workstations in the AD network. Existing groups will also be available in the ThinLinc environment.

The integration is done using the Winbind component of Samba, an open source software suite used to integrate Linux and other UNIX-like operating systems with Windows. For more information on the Winbind component, see http://www.samba.org/samba/docs/man/Samba-HOWTO-Collection/winbind.html.

Figure 9.1.  Active Directory Integration in Single Machine Setup

Active Directory Integration in Single Machine Setup

Winbind works by quering the Active Directory servers for information about users and group. It then assigns a numerical identification to each user and group for use in Linux or Solaris, and stores the mapping between SID and uid (for users)/gid (for groups) in a database.

9.3.1.  Single Machine or Cluster Setup

This documentation is split into two parts. The first part is about how to integrate a single ThinLinc server in an AD environment. The second part contains the information needed when multiple ThinLinc servers in a load-balancing cluster are connected to the same AD. The first part is a prerequisite for the second. In an environment with multiple ThinLinc servers in the same cluster, first configure the master machine following the instruction for the single machine setup, then proceed following the instructions in the second part.

9.3.2.  Requirements

  • This documentation assumes that you are running Active Directory. It is also possible to connect to old-style NT4 Windows Domains using Winbind, but that is outside the scope of this document. Refer to the Samba HOWTO for details.

  • Use Samba 3.0.0 or newer on the ThinLinc Terminal Servers. Make sure you upgrade to the latest Samba available on your distribution to avoid bugs corrected in later versions.

  • Be sure to check if your distribution has any known AD-specific problems by reading Section 3.6, “ Platform Specific Notes ”.

  • Make sure the system time of the ThinLinc server is correct and in sync with the Windows Servers. Not keeping the time in sync can cause problems when using winbind. We recommend that you use NTP (Network Time Protocol) to synchronize your ThinLinc and Windows servers to a known time source. If you network has no NTP server, you can use a free server. See http://www.pool.ntp.org for information about a network of free-to-use NTP servers.

9.3.3.  Single Machine Setup

9.3.3.1.  Configuration using tools provided by the distribution

If your operating system provides configuration tools for setting up authentication against Active Directory, it is strongly recommended that you use them. On Linux distributions related to Red Hat such as Fedora and Red Hat Enterprise Linux, there is a command named system-config-authentication that can be used for this purpose. In SUSE-related Linux distributions, configuration can be done in YaST under Network Clients.

Verify successful configuration using the instructions in Section 9.3.4, “ Verifying AD Integration ”.

9.3.3.2.  Manually configuring Samba

If your operating system lacks tools for configuring Samba, you need to configure Samba manually using the instructions below.

  1. Begin by configuring Kerberos. Find out what kerberos realm your AD installation has, and write it into /etc/krb5.conf. In our example, the kerberos realm is DOMAIN.EXAMPLE.COM. If you use a DNS server that is aware of Active Directory, it will contain information about where to find the KDC (Key Distribution Center), which means the amount of kerberos configuration on the ThinLinc server can be kept at a minimum.

    [libdefaults]
    	default_realm = DOMAIN.EXAMPLE.COM
    

    For Kerberos to automatically find your AD server, your DNS should contain a SRV record for _kerberos-master._udp.<YOUR KERBEROS REALM> as well as an SRV record for _kerberos-master._tcp.<YOUR KERBEROS REALM>, both of them pointing to your AD server. These entries are automatically added in networks where the AD server is configured to update DNS.

    If your DNS lacks this information, specify the hostname of the AD server as KDC in /etc/krb5.conf. Also add a dns_lookup_kdc = false statement to prevent the kerberos libraries from trying to find the KDC via DNS lookups.

    [libdefaults]
    	default_realm = DOMAIN.EXAMPLE.COM
            dns_lookup_kdc = false
    
    [realms]
            DOMAIN.EXAMPLE.COM = {
            kdc = adserver.example.com
    	}
    
  2. Verify your Kerberos configuration by trying to get a Kerberos ticket for an Active Directory user.

    # kinit user1@DOMAIN.EXAMPLE.COM
    Password for testuser@DOMAIN.EXAMPLE.COM: 
    
    # klist -5
    Ticket cache: FILE:/tmp/krb5cc_0
    Default principal: testuser@DOMAIN.EXAMPLE.COM
    
    Valid starting     Expires            Service principal
    11/07/06 13:58:31  11/07/06 23:58:31  krbtgt/DOMAIN.EXAMPLE.COM@DOMAIN.EXAMPLE.COM
    

    Note

    It's very important that the kerberos domain is specified using ALL-UPPERCASE characters.

    After the test, destroy the ticket by running the kdestroy command.

  3. Continue by configuring Winbind. This is done by editing /etc/samba/smb.conf. A minimal smb.conf is provided below:

    [global]
    # The default workgroup 
    workgroup = DOMAIN
    # security = ads is used when connecting to Active Directory 
    security = ads
    # The Kerberos domain
    realm = DOMAIN.EXAMPLE.COM
    encrypt passwords = true
    # The ranges for uid and gid assigned to users/groups from Active Directory
    idmap uid = 16777216-33554431
    idmap gid = 16777216-33554431
    # The shell used for users from Active Directory
    template shell = /bin/bash
    # Let users from the default domain appear as just <username>
    winbind use default domain = true
    # Hostname of AD server. Only needed if your DNS infrastructure 
    # does not contain relevant information.
    #password server = adserver.example.com
    
    • workgroup is set to the domain the computer should be joined to.

    • security = ads ensures that Winbind connects to the Active Directory using the AD/Kerberos approach.

    • realm lists the kerberos realm which should be the same as the realm we added to /etc/krb5.conf

    • idmap uid and idmap gid tells Winbind which ranges to use for uid's and gid's allocated to users and groups from Active Directory. Make sure you choose a range that is not used for other users and groups on the system.

    • template shell lists the shell used for users that originate from Active Directory.

    • winbind use default domain can be set to true to allow users in the domain listed in workgroup to login without specifying the domain name. For users in other domains, the username will be <DOMAIN\username>.

    • password server tells samba the hostname of the AD server. This only needs to be supplied if the DNS used by the ThinLinc server does not contain the relevant information. If the DNS contains a SRV entry for _ldap._tcp.pdc._msdcs.<YOUR KERBEROS REALM>, pointing to the AD server, Samba will find the address of the password server automatically. This information is automatically added to DNS by AD in networks where the AD server is configured to update DNS.

  4. Join the domain. For this you need access to the password of an administrative user.

    net ads join -U Administrator
    Administrator's password: 
    Using short domain name -- DOMAIN
    Joined 'HOSTNAME' to realm 'DOMAIN.EXAMPLE.COM'
    
  5. Start Winbind.

    # /etc/init.d/winbind start
    
  6. Configure the Name Service Switch library by editing /etc/nsswitch.conf. The lines beginning with passwd: and group: needs to be changed into the following:

    passwd:       files winbind
    group:        files winbind
    
  7. You should now be able to fetch information on users by running getent passwd <username> as described in Section 9.3.4, “ Verifying AD Integration ”.

  8. The Pluggable Authentication Modules (PAM) subsystem must now be configured to allow users to authenticate to Active Directory, for example when logging in via ssh.

    Since every Linux distribution has its own way of configuring PAM, we will only describe in general terms what needs to be configured. Adapt the information given here to the layout of the PAM configuration for your distribution.

    Common to most Linux distributions is that the configuration files for PAM reside in the directory /etc/pam.d.

    • Adapt the auth section of the PAM configuration to include pam_winbind.so. An example follows:

      auth	sufficient	pam_unix.so nullok_secure
      auth 	sufficient	pam_winbind.so use_first_pass
      auth	required	pam_deny.so
      
    • Adapt the account section of the PAM configuration to include pam_winbind.so. An example follows:

      account sufficient      pam_unix.so
      account sufficient      pam_winbind.so
      
    • If you want home directories to be created automatically at login, adapt the session section of the PAM configuration as below. Note that this behaviour can also be accomplished by using the homedir creation features of VSM Agent.

      session	required	pam_unix.so
      session required        pam_mkhomedir.so skel=/etc/skel
      

      Note

      If pam_mkhomedir is used, turn off PrivilegeSeparation in ssh, or creation of home directories will not work.

You should now be able to verify the AD integration as detailed in Section 9.3.4, “ Verifying AD Integration ”.

9.3.4.  Verifying AD Integration

After configuring Winbind, verify that everything works as expected following the procedure below.

  1. Verify that nscd (the Name Service Caching Daemon) is not running. According to the winbind documentation, it's under no cirumstances recommended to run nscd on a system running winbind.

    If nscd is running, stop it and make sure it's not started at system bootup.

    Winbind has its own cache to ensure good performance.

  2. Verify that the Kerberos configuration is correct by trying to get a Kerberos ticket for an Active Directory user:

    # kinit user1@DOMAIN.EXAMPLE.COM
    Password for testuser@DOMAIN.EXAMPLE.COM: 
    
    # klist -5
    Ticket cache: FILE:/tmp/krb5cc_0
    Default principal: testuser@DOMAIN.EXAMPLE.COM
    
    Valid starting     Expires            Service principal
    11/07/06 13:58:31  11/07/06 23:58:31  krbtgt/DOMAIN.EXAMPLE.COM@DOMAIN.EXAMPLE.COM
    

    Note

    It's very important that the kerberos domain is specified using ALL-UPPERCASE characters.

    After the test, destroy the ticket by running the kdestroy command.

    If this test doesn't work verify that the Kerberos configuration is correct as documented in Section 9.3.3.2, “ Manually configuring Samba ”.

  3. Verify that the computer is part of the domain by running net ads testjoin.

     # net ads testjoin
    Join is OK
    

    If this test doesn't work verify that the configuration of samba is correct as documented in Section 9.3.3.2, “ Manually configuring Samba ”. Then try joining the domain as documented in the same section.

  4. Verify that you can list users and groups in the domain using the wbinfo command. wbinfo -g should return a list of the groups from your domain, and wbinfo -u should return a list of users from your domain. For large domains, abort the listing after a few users by pressing Ctrl-C, to avoid having to wait for the whole list.

    If this test doesn't work something is wrong with your domain join. Inspect the Samba logs as well as the logs on the Active Directory server.

  5. Verify that you can do lookups for single AD users and groups using the getent command as below:

    # getent passwd testuser
    testuser:x:12580:10000:testuser:/home/DOMAIN/testuser:/bin/bash
    
    # getent group testgroup
    testgroup:x:10222:testuser
    

    If wbinfo -g and wbinfo -u works, but getent passwd testuser and/or getent group testuser fails to produce expected results, the problem is probably located in the NSS library rather than in the Winbind setup. Verify that the NSS configuration is correct as documented in Section 9.3.3.2, “ Manually configuring Samba ”.

  6. Restart ssh. Then verify that you can login via ssh to localhost as an AD user.

    Provide the AD password for the user when asked for password.

    # ssh testuser@localhost
    Password: 
    Last login: Thu Nov  2 10:18:44 2006 from testhost.example.com
    testuser@thinlinc-server:~> 
    

    If this test doesn't work, something is probably wrong with your PAM configuration. Verify that the PAM configuration is correct as documented in Section 9.3.3.2, “ Manually configuring Samba ”.

  7. Restart vsmserver. Then verify that you can login via ThinLinc as an AD user.

9.3.5.  Cluster Configuration

Figure 9.2.  Active Directory Integration in a Cluster Setup

Active Directory Integration in a Cluster Setup

If your ThinLinc cluster has more than one server, the mapping between SID and uid as well as the mapping between SID and gid must be consistent on all nodes. If the mapping is not kept consistent, use of home directories mounted from the master node is not possible since the home directory ownership will be different.

To make sure the mapping is the same on all nodes, a distributed idmap backend is configured. In our case, we use an OpenLDAP server running on the master node to keep the information.

When there's a query for a user or group which is not in the local cache, winbind will contact the Active Directory server to fetch the SID of the username. It will then check the LDAP database to see if there is already a mapping between the SID and the uid. If not, it will assign a uid and add the mapping between the SID and the uid to the LDAP database where winbind on other nodes in the cluster can find the information when a query on this username is received. The same procedure is followed for groups.

It is worth to note that the translation between the numerical ID for users (uid) and its corresponding username as well as the mapping between the numerical ID for groups (gid) and its corresponding groupname does not work until there has been a request for the username or groupname. In practice, this means that if a file is owned by the user test, and you list the file on a machine where test has not been logged in, the file will not be listed as owned by test but instead by the numerical id of test. If this is a problem in your environment, setup a cron job to fetch the full list of users and the full list of groups by running getent passwd and getent group at regular intervals. Note that this might not be a good idea in environments with large amounts of users, and that user and group enumeration must be turned on in the winbind configuration for it to work.

9.3.5.1.  Initial Configuration on the Master Server

Start by configuring the master server as detailed in Section 9.3.3, “ Single Machine Setup ” and verify that users and groups from AD are available in the system as detailed in Section 9.3.4, “ Verifying AD Integration ”.

9.3.5.2.  LDAP Server Configuration on the Master Server

The Master Server will run an OpenLDAP server to hold idmap information. Configure it as follows.

  1. Install OpenLDAP server, preferrably via the package system in your operating system.

  2. OpenLDAP server now needs configuration. The following summarizes the configuration:

    • The LDAP server is configured to hold a database with toplevel being the container ou=idmap.

    • A cn=manager,ou=idmap object is created with a unique password, then used as administrative user object by Samba.

    • The samba3 schema is added to the list of schema files. In practice, this means a line like the following needs to be added to the OpenLDAP server configuration file.

      include         /etc/openldap/schema/samba3.schema
      

      Adjust the path to the schema file to fit the location on your distribution.

    • Indices are configured to ensure high performance for the most common queries made by samba.

    The exact configuration needed on your server will vary depending on how your operating system's OpenLDAP package is configured. We will provide an example configuration file. Use this as a base for your own configuration file. The OpenLDAP server configuration file is named slapd.conf and is often located in /etc/openldap or in /etc/ldap.

    #
    # See slapd.conf(5) for details on configuration options.
    # This file should NOT be world readable.
    #
    include         /etc/openldap/schema/core.schema
    include         /etc/openldap/schema/cosine.schema
    include         /etc/openldap/schema/inetorgperson.schema
    # rfc2307bis.schema is sometimes called nis.schema
    include         /etc/openldap/schema/rfc2307bis.schema
    # the samba schema might also be found as
    # /usr/share/doc/samba-*/LDAP/samba.schema
    include         /etc/openldap/schema/samba3.schema
    
    pidfile         /var/run/slapd/slapd.pid
    argsfile        /var/run/slapd/slapd.args
    
    sizelimit unlimited
    
    # Simple access control policy. 
    # Allow access to base and subschema to make life easier for software
    # trying to figure out how this database is configure
    # Deny access to everything except for cn=manager,ou=idmap which can
    # read/write all objects.
    
    access to dn.base=""
            by * read
    
    access to dn.base="cn=Subschema"
            by * read
    
    access to *
            by dn=cn=manager,ou=idmap write
    
    
    #######################################################################
    # Database definitions
    #######################################################################
    
    database        bdb
    suffix          "ou=idmap"
    checkpoint      1024    5
    cachesize       10000
    
    rootdn          "cn=manager,ou=idmap"
    # Cleartext passwords, especially for the rootdn, should
    # be avoided.  See slappasswd(8) and slapd.conf(5) for details.
    # Use of strong authentication encouraged.
    rootpw          {SSHA}lI2oi67YjRQNLh56SquakxVS0zd4kb+7
    
    # The database directory MUST exist prior to running slapd AND 
    # should only be accessible by the slapd and slap tools.
    # Mode 700 recommended.
    directory       /var/lib/ldap
    
    # Indices to maintain
    index   objectClass     eq
    index   sambaSID              eq
    index   sambaPrimaryGroupSID  eq
    index   sambaDomainName       eq
    

    Note

    The template above is also available as /opt/thinlinc/share/samba/slapd.conf.template

    Note

    Pay special attention to the sizelimit unlimited statement and make sure its included in your configuration, or the verification of the idmap will not work as intended.

    Be sure to change the following in your configuration file compared to the template

    • Set the rootpw using a unique password generated by you for this purpose. Do this by running the slappasswd command supplying a unique password when asked for. Store away this password somewhere as you'll need it when configuring samba. Copy the string produced by slappasswd to the rootpw line in slapd.conf

    • Verify that the paths used for the include lines, the pidfile and argsfile parameters as well as the directory parameter are correct given the layout of your OpenLDAP installation.

  3. Continue by initializing the LDAP database with skeleton entries. Follow this procedure:

    1. Stop the OpenLDAP server. Do this by finding out the name of the init script for the ldap server on your distribution, then run it with the parameter stop. The init script is named /etc/init.d/ldap on many distributions.

      # /etc/init.d/ldap stop
      
    2. Initialize the LDAP database by loading /opt/thinlinc/share/samba/idmap-template.ldif

      # slapadd < /opt/thinlinc/share/samba/idmap-template.ldif
      
    3. Verify that the ownership of the database files created when running the above slapadd command is correct. On many distributions, the database files, typically located under /var/lib/ldap, must be owned by a non-root user, or the OpenLDAP server will fail to start.

    4. Start the OpenLDAP server.

      # /etc/init.d/ldap start
      
  4. Verify that you can connect to the LDAP server using the password previously set in slapd.conf

    # ldapsearch -x -b ou=idmap -h localhost -D cn=manager,ou=idmap -w <password>
    

    This should write output similar to the following:

    # extended LDIF
    #
    # LDAPv3
    # base <ou=idmap> with scope subtree
    # filter: (objectclass=*)
    # requesting: ALL
    #
    
    # idmap
    dn: ou=idmap
    objectClass: organizationalUnit
    objectClass: sambaUnixIdPool
    ou: idmap
    description: Posix and Samba LDAP Identity Database
    
    # manager, idmap
    dn: cn=manager,ou=idmap
    objectClass: organizationalRole
    cn: Manager
    description: Directory Manager
    
    # search result
    search: 2
    result: 0 Success
    
    # numResponses: 3
    # numEntries: 2
    
  5. Configure your operating system to start OpenLDAP at system bootup, before winbind.

9.3.5.3.  Winbind Configuration on the Master Server

With the LDAP server in place, it's time to configure the Winbind daemon on the master server.

In short, we change the idmap backend of Winbind. We also transfer old idmap information from the file-based database used previously to make sure we keep the same mappings between uid/SID and gid/SID.

Proceed as follows:

  1. Stop winbind

    # /etc/init.d/winbind stop
    
  2. Dump the existing winbind database into a textfile. First, locate the file winbindd_idmap.tdb. Common locations are /var/cache/samba or /var/db/samba/. Second, run net idmap dump <filename>.

    # net idmap dump \
    /var/cache/samba/winbindd_idmap.tdb > /root/idmap.out
    
  3. Move the old winbindd_idmap.tdb and winbindd_cache.tdb to a backup location. If this is not done, Winbind will not populate the LDAP database with the new data when we read the idmap information back in a later stage.

    # mv /var/cache/samba/winbindd_idmap.tdb /var/cache/samba/winbindd_idmap.tdb.old
    
    # mv /var/cache/samba/winbindd_cache.tdb /var/cache/samba/winbindd_cache.tdb.old
    
  4. Change idmap backend for winbind. Do this by setting the following in /etc/samba/smb.conf.

    idmap backend = ldap:ldap://masterhost.example.com
    ldap admin dn = cn=manager,ou=idmap
    ldap suffix = ou=idmap
    

    Replace masterhost.example.com with the hostname of your server.

  5. Set the password for the ldap admin dn using the smbpasswd command. Use the password you set as rootpw in slapd.conf generated with the slappasswd command.

    Note

    Do not use the hashed version of the password that you wrote into slapd.conf. Use the password you supplied when slappasswd asked for a password.

    # smbpasswd -w <password>
    
  6. Load the idmap information into the new idmap backend using the file we created using net idmap dump.

    # net idmap restore < /root/idmap.out
    

    This will load the data into the LDAP database. For large installations, this can take a while.

  7. Run tl-idmap-tool correctidmap to verify that the idmap written to LDAP is correctly configured. Failure to do this might cause duplicate use of uidNumber or gidNumber values.

    The tl-idmap-tool correctidmap command will ask you for a password. Use the password you set as rootpw in slapd.conf generated with the slappasswd command.

  8. Start winbind.

    # /etc/init.d/winbind start
    

Samba Configuration on the master server is now complete. You should be able to verify operations as described in Section 9.3.4, “ Verifying AD Integration ”.

9.3.5.4.  Initial Configuration on Agent Servers

After completion of the LDAP and Winbind configuration on the master server, each agent server in the ThinLinc cluster needs to be configured.

Start by configuring the agent server as detailed in Section 9.3.3, “ Single Machine Setup ” and verify that users and groups from AD are available in the system as detailed in Section 9.3.4, “ Verifying AD Integration ”.

Note that this will give you an idmap which is not consistent with the other servers in the cluster. It is however wise to use the tools provided by your operating system to do the initial AD configuration, joining the AD etc, then modifying the configuration for cluster operations. This way, most of the configuration can be made using easy to use tools, leaving only some details to be manually configured.

Warning

Do not let users login to the agent before Winbind configuration has been completed, or there will be confusion in file ownership.

9.3.5.5.  Winbind Configuration on Agent Servers

Configure Winbind for Cluster Operations by following the procedure below.

  1. Stop winbind

    # /etc/init.d/winbind stop
    
  2. Move the old winbindd_idmap.tdb and winbindd_cache.tdb to a backup location. If this is not done, Winbind will not query the LDAP database for new data but instead use the old data in the .tdb-files.

    # mv /var/cache/samba/winbindd_idmap.tdb /var/cache/samba/winbindd_idmap.tdb.old
    
    # mv /var/cache/samba/winbindd_cache.tdb /var/cache/samba/winbindd_cache.tdb.old
    
  3. Change idmap backend for winbind. Do this by setting the following in /etc/samba/smb.conf.

    idmap backend = ldap:ldap://masterhost.example.com
    ldap admin dn = cn=manager,ou=idmap
    ldap suffix = ou=idmap
    

    Replace masterhost.example.com with the hostname of your server.

  4. Set the password for the ldap admin dn using the smbpasswd command. Use the password you set as rootpw in slapd.conf generated with the slappasswd command.

    Note

    Do not use the hashed version of the password that you wrote into slapd.conf. Use the password you supplied when slappasswd asked for a password.

    # smbpasswd -w <password>
    
  5. Start winbind.

    # /etc/init.d/winbind start
    

Samba Configuration on the Agent server is now complete. You should be able to verify operations as described in Section 9.3.4, “ Verifying AD Integration ”. After verifying, enable the agent in the VSM Server configuration to allow user sessions.