Linux, Active Directory, and Windows Server 2003 R2 Revisited

UPDATE: A revised version of these instructions is available here.

The integration of (what was formerly called) Services for UNIX into Windows Server 2003 R2 also brought some other changes; most notably, a change in the schema.  To accommodate those changes, I’ve updated my Linux-AD integration instructions (the previous instructions are here for pre-R2 versions of Windows).  If you need to integrate Linux systems for authentication into Active Directory with Windows Server 2003 R2, these instructions should get you there.  (Note that a previous version of these instructions is also available.)

For the most part, these instructions are reasonably similar to the instructions for pre-R2 versions of Windows.

Preparing Active Directory (One-Time)

Based on what I’ve seen so far, it appears as if a partial RFC 2307-compliant schema is included by default with Windows Server 2003 R2.  This means that it is no longer necessary to extend the schema to include attributes such as uid, gid, login shell, etc.  However, while the schema does appear to be present by default (based on explorations using ADSI Edit), you must install the “Server for NIS” component on at least one domain controller in order to be able to actually set those attributes (and it will be necessary to set those attributes using the Active Directory Users and Computers console before logins from Linux will work).

However, to optimize Active Directory logins from Linux systems, it’s also necessary to index the uid attribute in Active Directory.  By default, most PAM-enabled systems use the uid attribute as the default login attribute (refer to the “pam_login_attribute” parameter in the /etc/ldap.conf file).  Logins will work without having this attribute indexed, but as was discovered in a recent VAS installation, this can introduce delays and drive CPU utilization through the roof.  Use the Schema Management MMC snap-in to check the box labeled “Index this attribute in the Active Directory” for the uid attribute.  (If you don’t want to index the uid attribute, change the value of the pam_login_attribute to something like sAMAccountName, which is already indexed.)

Next, create a new global security group that will act as the default group for Linux-enabled users.  Be sure to set the values on the “UNIX Attributes” tab for this group.  Add the users that will authenticate to this group using both the “Members” tab and the members list on the “UNIX Attributes” tab.

Finally, you’ll also need to create an account in Active Directory that will be used to bind to Active Directory for LDAP queries.  This account does not need any special privileges; in fact, making the account a member of Domain Guests and not a member of Domain Users is perfectly fine.

Each of these tasks are one-time tasks that must be accomplished before logins from Linux will work.  Once they have been completed, you are ready to configure the individual users.

Preparing Active Directory (Each User)

Each Active Directory account that will authenticate via Linux must be configured with a uid and other UNIX attributes.  This is accomplished via the new “UNIX Attributes” tab on the properties dialog box of a user account.  Installing the “Server for NIS” component enables this new tab, as mentioned previously.

Each user must be given an NIS domain, but this parameter is ignored in our authentication scheme.  Each user must also have a unique uid; I believe that the Server for NIS defaults at a starting uid of 10000, which is pretty safe for most systems.  In addition, each member must have a gid (group ID); simply specify the group that was created earlier.  Be sure to also specify a login shell (such as “/bin/bash”) and a home directory (such as “/home/slowe”).

After all the user accounts have been configured, then we are ready to perform the additional tasks within Active Directory and on the Linux server that will enable the authentication.

Preparing Active Directory (Each Linux Server)

Here is where it starts getting tricky.  So far, nothing we’ve done has been unusual or terribly difficult.  Things will start getting a bit more complex now.

First off, you’ll need to decide if you want to use TGT validation.  I don’t have the space here to fully describe this, but basically it’s a check that the Kerberos Key Distribution Center (KDC—in this case, an Active Directory domain controller) is not being spoofed.  It’s an added level of security that ensures that all hosts involved are indeed who they say they are, which is one of the core principles of the Kerberos authentication system.

Without TGT Validation

If you don’t care about TGT validation, then ignore this whole section and proceed to “Preparing Each Linux Server”, below.  Once Linux is properly configured for Kerberos authentication and LDAP lookups, it can authenticate against Active Directory with no further action required.  You’ll note that this is in contrast to many of the instructions out there (including my original instructions), which state that you must perform additional steps.  In my experience, the additional steps are only necessary if you want TGT validation, i.e., if you want the Linux server to verify the identity of the Active Directory domain controller handing out the Kerberos tickets.  If you don’t care about that, then you’re ready to proceed with the next step.

With TGT Validation

For each Linux-based server that will be authenticating against Active Directory, follow the steps below.

  1. Create a computer account in Active Directory.  When creating the computer account, be sure to specify that this account may be used by a pre-Windows 2000–based computer.
  2. Use the following command at a command prompt to configure the new computer account:
    ktpass -princ HOST/fqdn@REALM -mapuser DOMAIN\name$
    -crypto DES-CBC-MD5 +DesOnly -pass password -ptype KRB5_NT_SRV_HST
    -out filename

    Of course, you’ll need to substitute the appropriate values for “fqdn” (the fully-qualified domain name of the computer), “REALM” (the DNS name of your Active Directory domain in UPPERCASE), “DOMAIN” (the NetBIOS name of your Active Directory domain), “name$” (the name of the computer account created, with a dollar sign appended at the end), “password” (the password that will be set for the new computer account), and “filename” (the keytab that will be generated and must be copied over to the Linux computer).  Please note (and this is important) that the “HOST/fqdn@REALM” portion is case-sensitive and should be typed as shown above.#160; Of course, if you are repeating this process for multiple servers, please be sure to use a unique filename for each keytab generated using ktpass.exe.  (I use each Linux server’s hostname as the filename.)

If this computer account ever gets deleted from Active Directory, then Active Directory users will be unable to authenticate to Linux systems.  You’ll need to repeat the process—create a new computer account, run ktpass.exe, and copy the keytab over to the Linux server (as described below).

Preparing Each Linux Server

Follow the steps below to configure each Linux server for authentication against Active Directory.

  1. Make sure that the appropriate Kerberos libraries, OpenLDAP, pam_krb5, and nss_ldap are installed.  If they are not installed, install them.
  2. Be sure that time is being properly synchronized between Active Directory and the Linux server in question.  Kerberos requires time synchronization.  Set up NTP if necessary.
  3. Edit the krb5.conf file to look something like this, substituting your actual host names and domain names where appropriate:
    [logging]
     default = FILE:/var/log/krb5libs.log
     kdc = FILE:/var/log/krb5kdc.log
     admin_server = FILE:/var/log/kadmind.log
    
    [libdefaults]
     default_realm = EXAMPLE.COM
     dns_lookup_realm = true
     dns_lookup_kdc = true
    
    #[realms]
    # EXAMPLE.COM = {
    #  kdc = host.example.com:88
    #  admin_server = host.example.com:749
    #  default_domain = example.com
    # }
    
    [domain_realm]
     .example.com = EXAMPLE.COM
     example.com = EXAMPLE.COM
    
    [kdc]
     profile = /var/kerberos/krb5kdc/kdc.conf
    
    [appdefaults]
     pam = {
       debug = false
       ticket_lifetime = 36000
       renew_lifetime = 36000
       forwardable = true
       krb4_convert = false
       validate = true
     }

    Note that the line “validate =” should be set to true if you want TGT validation; otherwise, set it to false.  Note also that we’ve commented out the [realms] section because we are using DNS to locate the KDCs (“dns_lookup_kdc = true”); this requires the presence of the appropriate SRV records in DNS.  In a correctly-functioning Active Directory environment, these records will be present.

  4. Edit the /etc/ldap.conf file to look something like this, substituting the appropriate host names, domain names, account names, and distinguished names (DNs) where appropriate.
    host 10.10.10.10
    base dc=example,dc=com
    uri ldap://server.example.com/
    binddn ldap@example.com
    bindpw adldapbindpw
    scope sub
    ssl no
    pam_filter objectClass=User
    nss_base_passwd dc=example,dc=com?sub
    nss_base_shadow dc=example,dc=com?sub
    nss_base_group dc=example,dc=com?sub
    nss_map_objectclass posixAccount user
    nss_map_objectclass shadowAccount user
    nss_map_objectclass posixGroup group
    nss_map_attribute gecos name
    nss_map_attribute homeDirectory unixHomeDirectory
    nss_map_attribute uniqueMember member
  5. Securely copy the file generated by the ktpass.exe command above to the Linux server.  You can replace the existing /etc/krb5.keytab file if and only if you do not need any of the existing keys stored there.  If you haven’t put any keys in there, then you probably don’t have any and don’t need to worry about using ktutil to merge the new keys (from the file generated by ktpass.exe) with the existing keys.  If, however, you do have existing keys you need to maintain, be sure to use ktutil to merge/append the new keys to the existing keytab.
  6. Configure PAM (this varies according to Linux distributions) to use pam_krb5 for authentication.  Many modern distributions use a stacking mechanism whereby one file can be modified and those changes will applied to all the various PAM-aware services.  For example, in Red Hat-based distributions, the system-auth file is referenced by most other PAM-aware services.  A sample system-auth file that would be found in /etc/pam.d might look something like this:
    #%PAM-1.0
    # This file is auto-generated.
    # User changes will be destroyed the next time authconfig is run.
    auth      required    /lib/security/$ISA/pam_env.so
    auth      sufficient  /lib/security/$ISA/pam_unix.so likeauth nullok
    auth      sufficient  /lib/security/$ISA/pam_krb5.so
    auth      required    /lib/security/$ISA/pam_deny.so
    
    account   sufficient  /lib/security/$ISA/pam_krb5.so
    account   required    /lib/security/$ISA/pam_unix.so
    account   sufficient  /lib/security/$ISA/pam_succeed_if.so uid < 100 quiet
    account   required    /lib/security/$ISA/pam_deny.so
    
    password  requisite   /lib/security/$ISA/pam_cracklib.so retry=3
    password  sufficient  /lib/security/$ISA/pam_unix.so nullok \use_authtok md5 shadow
    password  required    /lib/security/$ISA/pam_deny.so
    
    session   required    /lib/security/$ISA/pam_limits.so
    session   required    /lib/security/$ISA/pam_unix.so

    (Lines have been wrapped above for readability, but should be typed all on a single line.)  Of course, each distribution’s PAM configuration may be different, so be sure to consult the documentation for your particular distribution.  The sample above was taken from CentOS 4.3, with a few modifications.  Remember that in Red Hat-based distributions, such as CentOS, running the authconfig program will overwrite all the changes to /etc/pam.d/system-auth, so be careful.

  7. Edit the /etc/nsswitch.conf file to include “ldap” as a lookup source for passwd, shadow, and groups.

That should be it.  Once you do that, you should be able to use kinit from a Linux shell prompt (for example, “kinit aduser”) and generate a valid Kerberos ticket for the specified Active Directory account.

At this point, any PAM-aware service that is configured to use the stacked system file (such as the system-auth configuration on Red Hat-based distributions) will use Active Directory for authentication.  The SSH daemon is a good one to test.  Note, however, that unless you also add the pam_mkhomedir.so module in the PAM configuration, home directories will have to be created manually (with the correct permissions and ownership set manually as well) for any Active Directory account that may log on to that server.  (I generally recommend the use of pam_mkhomedir.so in this situation.)

Caveats/Limitations/Disclaimers

I haven’t tested this configuration on every possible distribution of Linux.  This configuration was tested on CentOS 4.3 running as a virtual machine under ESX Server 3.0, authenticating against a pair of domain controllers running Windows Server 2003 R2 (which were also VMs).  It should work without major modifications on most other Linux distributions, and with modifications on various other Unix operating systems.  (I plan to test OpenBSD 3.9 and possibly Solaris 10 x86 soon.)

Also, even though the “validate = true” setting in /etc/krb5.conf implies that the Kerberos TGT must be validated, pam_krb5 appears to bypass the TGT validation if the keytab is not present or not readable.  This means that logins will succeed, even if the keytab is not present or not readable.  If the computer account in Active Directory is missing, however, logins will fail.  I know it’s odd; the only possible explanation I can offer is described in a follow-up posting regarding ESX-AD integration.

If anyone finds any errors, discrepancies, or inaccuracies in this article, please let me know and I’ll correct them as soon as possible.

Tags: , , , , , , ,

  1. Paul’s avatar

    Hello
    It was problem with DNS, when I added hostname and ip into hosts , it works OK.

  2. Andy’s avatar

    Scott,

    Thanks for the tips. I got everything working – it turns out part of the problem was the ktpass issue (http://support.microsoft.com/default.aspx?scid=kb;en-us;919557). Man, that was annoying. Anyone who is doing this should get that hotfix; it’s just one less variable.

    Now, have you, or anyone else, got this working over SSL? (I’m sure *someone* has; I just need them to say so). It looks like Scott (who posted above) was working on it and posted some of his config files over here: http://www.winlinanswers.com/community/viewtopic.php?t=37. I don’t know if this was his final working configuration.

    It would seem you need to:
    1. Generate a cert on the Windows AD DC.
    2. Export/copy it to a file.
    3. Copy that file to the Linux machine and convert it using the openssl command. Ensure you set the proper perms.
    4. Edit the /etc/ldap.conf and maybe the /etc/openldap/ldap.conf file.
    5. Maybe edit the /etc/pam.d/system-auth config file.

    I did 1-3 and seem to have that working (I can issue the open_ssl s_client -connect fqdn_of_the_dc:636 -CAFile cert_path and get valid info). Am I missing any steps? What changes neede to be made in the .conf files?

    Andy

  3. slowe’s avatar

    Andy,

    I have not gotten it working, but I haven’t tried, either–been busy working on other tasks. It seems that the two things people are most interested in out of this process is the Kerberos bind for LDAP (instead of using simple authentication) and LDAP over SSL. Hopefully I’ll get some time to work on those soon.

    I would imagine that the only thing that would need to be edited would be the /etc/ldap.conf, and in there you would specify “ssl on” and modify the LDAP URI (possibly the port as well). You should NOT have to modify anything pertaining to OpenLDAP; we are only concerned with the nss_ldap configuration, not OpenLDAP, and nss_ldap’s configuration is driven by /etc/ldap.conf (typically).

    Let me know if you make any progress.

    Scott

  4. David G’s avatar

    Scott,

    A couple of things that you may find interesting/useful – in Linux anyway:

    There is a much easier way to generate a host keytab with the Samba toolset – the steps are:

    1. Install the Samba server & tools – the main things you need are the Samba ‘net’ utility & the smb.conf (plus libraries, etc).
    2. Setup your /etc/krb5.conf as above.
    3. Edit the smb.conf file to include the following, substituting actual host names and domain names where appropriate:
    workgroup = EXAMPLE
    security = ads
    realm = example.com
    use kerberos keytab = yes
    4. As a root user, get a TGT for the Domain Admin (or user with Add Computer privs in AD): kinit Administrator@EXAMPLE.COM
    5. Still as root user join the host to the Windows Domain: net ads join

    You should now have a nice shiny /etc/krb5.keytab with host entries for your Linux host. Furthermore, you will have a ‘real’ computer account in your AD – much nicer than a ‘mapped’ user account I think.

    Gotta thank the Samba guys for this one.

    Also, Vintela (a.k.a. Quest) the makers of VAS which I’m sure you are aware of, have a nice set of patches for PuTTY which make single signon from Windows to Unix/Linux a reality. This version of PuTTY uses GSSAPI to negotiate the login authentication – no ssh private keys to manage.

    You can get it here: http://rc.vintela.com/topics/putty/

    HTH
    David

  5. slowe’s avatar

    David G,

    The Samba tools have been pointed out by a couple of readers, but I just haven’t had the chance to work with them yet. I would most certainly love to get back to a single computer object in Active Directory with multiple SPNs as necessary, but all attempts to make that work have failed thus far.

    Another reader also pointed out that the GSSAPI-patched PuTTY works well in these kinds of environments as well. Since I run Mac OS X, I haven’t tested it.

    Scott

  6. Andy’s avatar

    Scott,

    I wanted to follow up with you about LDAP over SSL. After some trial and error, I got it working. I had to do the steps I listed above.

    For step 3, I converted the cert using the command: openssl x509 -in cert-from-DC.cer -out cert-from-DC.per

    For step 4, I added these lines to the ldap.conf file:
    uri ldaps://fqdn-of-the-DC
    ssl on
    tls_checkpeer yes
    tls_cacertfile path-to-cert-name
    I also had to make sure the host name was a fqdn.

    I also had to uncomment out the [realm] section of the krb5.conf file and fill it in with fqdn. Actually, I think I did that to get TGT working. Nonethless, using IP’s didn’t seem to work; I had to have machine names in there.

    I’m trying to figure out how this would work if you had mulitple DCs. Can you have multiple names in the ldap.conf file for the ‘host’ and ‘uri’ vales? I’m going to play around with that next. If you have multiple DC’s, might as well use ‘em!

    Andy

  7. JonathanB’s avatar

    Scott,

    As David G says messing about with the Windows servers to get keytab files is a total unnecessary pain. Samba is the way to go, even for a workstation you just make sure there are no shares defined. A major advantage is that Samba will get renewing the tickets automatically.

    The other advantage is that you can get additional service tickets. Want to do GSSAPI Kerberos single signon authentication with Apache, then a simple net ads keytab add HTTP will get you a service principle keytab for HTTP. You can then configure Apache with mod_auth_kerberos and off you go.

    What I cannot get working is Kerberos authenticted LDAP searches. Using CentOS it is completely broken on 64 bit machines (several hours of head banging before I worked that one out). However on 32 bit machines I end up with the following error.

    ldap_sasl_interactive_bind_s: Local error (-2)
    additional info: SASL(-1): generic failure: GSSAPI Error: Miscellaneous failure (Server not found in Kerberos database)

    Ideas anyone!!

  8. slowe’s avatar

    JonathanB,

    Generally, the “server not found in Kerberos database” points to a Kerberos configuation error. Is the domain-realm mapping correct? I’ve seen a number of instances where the domain-realm mapping was incorrect (or missing) that resulted in that very error message.

    Scott

  9. slowe’s avatar

    Andy,

    I honestly don’t know if you can specify multiple LDAP servers or not. I’ll have to do some research and find out for you. Good work on getting SSL/TLS working with LDAP!

    Scott

  10. David’s avatar

    Actually the su command is only half working. When I login as root and try to su to a local account I get the error message “su: incorrect password”. I’m successfull if I su to an AD account. I’m also not able to login to the console with locally created accounts other than root. I get the error message that the user account has expired. I know it must have something to do with the pam config files su and login but not sure what to change. Thanks

    – Dave

  11. David’s avatar

    Ok, I’m still having problems with using the sudo and su commands as well as others. For some reason local accounts are still trying to be authenticated via kerberos. When I try to su to an AD account it works fine but to any local account it fails with the error message “su: incorrect password”. Here’s the log entry in /var/log/messages when I try to login with the postgres user account.

    Dec 12 20:06:07 tlinux01 login(pam_unix)[21909]: authentication failure; logname=LOGIN uid=0 euid=0 tty=tty1 ruser= rhost= user= postgres
    Dec 12 20:06:12 tlinux01 login[21909]: pam_krb5[21909]: authentication fails for ‘postgres’ (postgres@LINUX.LOCAL): User not know n to the underlying authentication module (Client not found in Kerberos database)
    Dec 12 20:06:14 tlinux01 login[21909]: FAILED LOGIN 1 FROM (null) FOR postgres, Authentication failure

    I’m also not able to login via the console with any local account (except for root). I continually get the error message that the user account has expired.

    This issue also breaks applications that require being runned by a user other than root. For example this broke my PostgreSQL install since it tries to authenticate the postgres user it runs as with kerberos and therefore fails to start since it’s not in AD.

    I thought if it fails the LDAP lookup that it falls back to using local authentication. Am I missing something? Thanks

    – Dave

  12. slowe’s avatar

    David,

    We’ll need to see the configuration files (krb5.conf, ldap.conf, and the appropriate PAM files) in order to really figure out what’s going on.

    Regards,
    Scott

  13. David’s avatar

    Here are my config files:

    ldap.conf

    host 172.20.16.72
    base dc=linux,dc=local
    binddn ldap@linux.local
    bindpw testing123
    scope sub
    ssl no
    nss_base_passwd dc=linux,dc=local
    nss_base_shadow dc=linux,dc=local
    nss_base_group dc=linux,dc=local
    nss_map_objectclass posixAccount user
    nss_map_objectclass shadowAccount user
    nss_map_objectclass posixGroup group
    nss_map_attribute uid sAMAccountName
    nss_map_attribute uidNumber msSFU30UidNumber
    nss_map_attribute gidNumber msSFU30GidNumber
    nss_map_attribute loginShell msSFU30LoginShell
    nss_map_attribute gecos name
    nss_map_attribute userPassword msSFU30Password
    nss_map_attribute homeDirectory msSFU30HomeDirectory
    nss_map_attribute uniqueMember msSFU30PosixMember
    nss_map_attribute cn cn

    krb5.conf

    [logging]
    default = FILE:/var/log/krb5libs.log
    kdc = FILE:/var/log/krb5kdc.log
    admin_server = FILE:/var/log/kadmind.log

    [libdefaults]
    default_realm = LINUX.LOCAL
    dns_lookup_realm = true
    dns_lookup_kdc = true

    #[realms]
    # EXAMPLE.COM = {
    # kdc = kerberos.example.com:88
    # admin_server = kerberos.example.com:749
    # default_domain = example.com
    # }

    [domain_realm]
    .linux.local = LINUX.LOCAL
    linux.local = LINUX.LOCAL

    [kdc]
    profile = /var/kerberos/krb5kdc/kdc.conf

    [appdefaults]
    pam = {
    debug = true
    ticket_lifetime = 36000
    renew_lifetime = 36000
    forwardable = true
    krb4_convert = false
    validate = false
    }

    nsswitch.conf

    passwd: ldap files
    shadow: ldap files
    group: ldap files

    /etc/pam.d/system-auth

    #%PAM-1.0
    # This file is auto-generated.
    # User changes will be destroyed the next time authconfig is run.
    auth required /lib/security/$ISA/pam_env.so
    auth sufficient /lib/security/$ISA/pam_unix.so likeauth nullok
    auth sufficient /lib/security/$ISA/pam_krb5.so debug=true
    auth required /lib/security/$ISA/pam_deny.so

    account sufficient /lib/security/$ISA/pam_krb5.so debug=true
    account required /lib/security/$ISA/pam_unix.so
    account sufficient /lib/security/$ISA/pam_succeed_if.so uid < 100 quiet
    account required /lib/security/$ISA/pam_deny.so

    password requisite /lib/security/$ISA/pam_cracklib.so retry=3
    password sufficient /lib/security/$ISA/pam_unix.so nullok use_authtok md5 shadow
    password required /lib/security/$ISA/pam_deny.so

    session required /lib/security/pam_mkhomedir.so skel=/etc/skel umask=0022
    session required /lib/security/$ISA/pam_limits.so
    session required /lib/security/$ISA/pam_unix.so

    /etc/pam.d/su

    #%PAM-1.0
    auth sufficient /lib/security/$ISA/pam_rootok.so
    # Uncomment the following line to implicitly trust users in the “wheel” group.
    #auth sufficient /lib/security/$ISA/pam_wheel.so trust use_uid
    # Uncomment the following line to require a user to be in the “wheel” group.
    #auth required /lib/security/$ISA/pam_wheel.so use_uid
    auth required /lib/security/$ISA/pam_stack.so service=system-auth
    account required /lib/security/$ISA/pam_stack.so service=system-auth
    password required /lib/security/$ISA/pam_stack.so service=system-auth
    # pam_selinux.so close must be first session rule
    session required /lib/security/$ISA/pam_selinux.so close
    session required /lib/security/$ISA/pam_stack.so service=system-auth
    # pam_selinux.so open and pam_xauth must be last two session rules
    session required /lib/security/$ISA/pam_selinux.so open
    session optional /lib/security/$ISA/pam_xauth.so

    /etc/pam.d/sudo

    #%PAM-1.0
    auth required pam_stack.so service=system-auth
    account required pam_stack.so service=system-auth
    password required pam_stack.so service=system-auth
    session required pam_limits.so

    /etc/pam.d/login

    #%PAM-1.0
    auth required pam_securetty.so
    auth required pam_stack.so service=system-auth
    auth required pam_nologin.so
    account required pam_stack.so service=system-auth
    password required pam_stack.so service=system-auth
    # pam_selinux.so close should be the first session rule
    session required pam_selinux.so close
    session required pam_stack.so service=system-auth
    session required pam_loginuid.so
    session optional pam_console.so
    # pam_selinux.so open should be the last session rule
    session required pam_selinux.so open

  14. David’s avatar

    Ok, I think I’ve figured out what the issue is. In my /etc/pam.d/system-auth file I changed this line:

    account sufficient /lib/security/$ISA/pam_succeed_if.so uid < 100 quiet

    to be:

    account sufficient /lib/security/$ISA/pam_succeed_if.so uid < 1000 quiet

    All my AD accounts have a UID greater than 1000 so this seems to work so far. I’m still testing but this seems to have fixed my problem.

    Another issue that has cropped up in my testing is that I can’t login with some of my AD accounts after I manually reset the password in AD. I keep getting the error message that the user account has expired. If I create a brand new account in AD I can login but if I manually change the password I can’t login anymore. Any ideas? Thanks

    – Dave

  15. David’s avatar

    Scott,

    For some reason I am still having the issue where I can’t login with an AD account after I manually reset the password. The only way around it is to delete the account and re-add it which is not feasible in a production environment. Have you run into this before or have any suggestions? Thanks

    – Dave

  16. slowe’s avatar

    David,

    I have not seen that problem at all. My Linux server crashed yesterday (unrelated problem) and I’m building another one today, so I’ll try to recreate the problem on my end and see if I can figure out what’s going on. Shoot me an e-mail (scott dot lowe at scottlowe dot org) and let’s move this discussion into an e-mail thread. Thanks!

  17. Elie’s avatar

    Scott,

    I have ssh form the unix host working from RHEL 4 Update 3 to windows 2003 R2 working, so thank you for you site. I have 1 question.. I get id: cannot find name for user ID once I ssh to my linux machine. Once logged in.. I can do id and get the proper username mapping of course since I set the correct permissions and ownership on my directories. Is there something missing from the ldap.conf file you posted above to get this to work. Thanks in advance.
    Elie.

  18. slowe’s avatar

    Elie,

    Does “getent passwd username” work properly? Are there any messages being logged that might help? As far as I am aware, the ldap.conf above is complete. However, feel free to check a few of my other Linux-AD articles (check the Interoperability category archives) and see if I inadvertently omitted something.

    Scott

  19. Elie’s avatar

    Scott, I found the problem… my ldap.conf file had 600 permissions set on it. Setting it to 644 solved the problem. Thank you for your great articles. Elie.

  20. Thomas’s avatar

    Hi!

    Thank you for this wonderful guide, following it I almost fionished without any problem.

    After completing each step i could request a ticket with kinit, however pam_krb5 seems to be corrupt. When I try to login i get access denied and these records in auth.log:

    Jan 19 16:15:49 localhost login[4968]: PAM unable to dlopen(/lib/security/pam_krb5.so)
    Jan 19 16:15:49 localhost login[4968]: PAM [dlerror: /lib/security/pam_krb5.so: undefined symbol: krb5_init_ets]
    Jan 19 16:15:49 localhost login[4968]: PAM adding faulty module: /lib/security/pam_krb5.so
    Jan 19 16:15:56 localhost login[4968]: (pam_unix) authentication failure; logname=gregoricst uid=0 euid=0 tty=pts/1 ruser= rhost= user=gregoricst
    Jan 19 16:15:59 localhost login[4968]: FAILED LOGIN (1) on `pts/1′ FOR `gregoricst’, Authentication failure

    I have no idea what should i do. I compiled pam_krb5 without any problems.

  21. slowe’s avatar

    Thomas,

    I can only suggest recompiling from source or installing a binary package for your distribution of Linux.

    Scott

  22. Thomas’s avatar

    Yes, i did install the binary packages and its working perfetly now ;)

  23. Mark Jenks’s avatar

    I followed your directions and included the directions of about 6 other websites.

    I have Ad_auth running with SSL_TLS and not having to specify a single hostname of an AD server. (All DNS/AD).

    Be aware, that if you want to use SSL_TLS like this, you need to get the hotfix from Microsoft that has a fixed KTPASS.exe. (took me 2 days to figure it out).

    So, it’s completely tied to to AD, secure on LDAPS.

    This is running on Centos 4.4.

    Contact me if you want a copy of my docs.

    -Mark

  24. slowe’s avatar

    Mark,

    Send your configs to me via e-mail. I’ll post them here and give you all the credit–you figured it out, after all.

    Scott

  25. Jason Sjobeck’s avatar

    Any ideas why kerberos auth’ would work for user to login to the box but when that user tries to do “sudo su -” then it does not like him? This is one oddity that seems specific to this openSUSE 10.2 box, since this user can “sudo su -” on all the other boxes (ie: CentOS 4.4 & openSUSE) in the org’. (I just realized I do not know how to increase the verbosity of sshd) Thanks much.

    One other tangental thought, there is not any traffic that has to go between the client & the AD server for kerberos auth to work, is there? The connectivity would flow from client on WAN, to ssh server (on NAT’d LAN) and then login auth request forwarded from sshd server to AD across LAN, back to sshd, then back to ssh client. But no traffic from ssh client to AD server (since no rule in firewall for that). That about correct? Thanks again.

  26. Jason Sjobeck’s avatar

    Scott,
    All,

    Please ignore my last post since I just copied my /etc/krb5.conf from my other working machine to the openSUSE 10.2 machine that was not working & all seems OK now. (I set them up in the exact same way, using YAST, same values, but one didnt work.)

    The only other thing I can think of to ask today is why when I have the variable/value pair of :

    GSSAPIAuthentcation Yes

    in my /etc/ssh/sshd_config file on this one machine does it complain upon “/etc/init.d/sshd restart” that:

    Shutting down SSH daemon done
    Starting SSH daemon/etc/ssh/sshd_config: line 67: Bad configuration option: GSSAPIAuthenication
    /etc/ssh/sshd_config: line 69: Bad configuration option: GSSAPICleanupCreds
    /etc/ssh/sshd_config: terminating, 2 bad configuration options
    startproc: exit status of parent of /usr/sbin/sshd: 255
    done

    Thanks all.

  27. Jason Sjobeck’s avatar

    Dont know why this is one of those days for me ….. finding answers to things right after I post the question ….. I just now found that the reason that my sshd daemon is whining about GSSAPI is that is supposedly not compiled with its support. It looks as if it was compiled with support for kerberos support but not GSSAPI. Perhaps something to take up with openSUSE. Peace & Love.

  28. alaxa’s avatar

    I’ve a problem that I don’t understand how to solve. But I think I found where it resides.
    The problem is that with our Suse10.1 each time I try to log in with a username, or simple rebooting the machine, there is some process (sshd, dbus, kdm ecc..) that goes up to 99% of CPU time.
    I found that this happen when the LDAP is searching for groups. If I comment these lines
    nss_base_group dc=domain,dc=explame,dc=com?sub?&(objectCategory=group)(gidnumber=*)
    nss_map_objectclass posixGroup Group

    everything works fine. I thought a conflict with builtin ‘users’ in the linux box (gid=100) and ‘domain users’ (gid=100) in the AD mapped as ‘users’, but changing bulitin ‘users’ to ‘users2′ and their GID, the problem persists.
    any suggestion is welcome

  29. slowe’s avatar

    Alaxa,

    The problem may be due to a need for an index on some of the AD attributes. Check some of my other AD integration articles and see if adding an index on the uid or gid attribute(s) helps solve the issue.

    Thanks,
    Scott

  30. alaxa’s avatar

    Thanks for the reply.
    I don’t understand, since two days ago the login process is working either with the group section activated!

    anyhow, just out of curiosity..
    I’m using the mapping service to map unix2AD accounts and I mapped ‘users’ (GID=100)to ‘Domain Users’. If I login in the unix shell I see that files are not owned by ‘users’ but by ‘domain users’. Is this correct?
    one more doubt: there could be conflicts if inside my linux box a group called ‘users’ already exists? Because I’ve removed ‘users’ from one linux box and I see ‘Domain Users’ for gid=100, but left ‘users’ in anohter linux machine and I correctly see ‘users’ listed for GID=100.
    thanks

  31. sysk’s avatar

    well scott you ARE the man, definitley :) I’m sure I gonna need your advisory/howto soon, and as eric s. raymond said someone is a h4x0r if people tell him he is – and so I do now, you ARE. respect and big thx…

  32. LC’s avatar

    Off topic:
    I will be doing a migration from NIS to AD and notice you have many blogs that looks like you did the same: Did you have a migration plan? If so you reply to me via email as I do not have a particular question just yet. What is your preferred method for linux servers userinfo/authentication to AD samba/ldap/kerberos/winbind etc.

  33. slowe’s avatar

    LC,

    I did not migrate from NIS to AD; I started out with AD integration instead of deploying NIS. However, for NIS migrations, you can import your NIS maps into the NIS server provided by Windows and use that along with the AD integration information provided here. My preferred method of providing AD integration with UNIX and Linux is to use Kerberos for authentication (and you can optionally use Samba, if ADS support was compiled in, to help with this) and LDAP for authorization (using nss_ldap or the equivalent). This seems to work pretty well.

    Hope this helps!

  34. MH’s avatar

    I have everything up and running but like others, I’m now unable to su – from any AD accounts. I can only su from my local linux accounts. When I try from my NA accounts I get incorrect password. It’s 04:23 and I’m ready to bang my head into the desk. Is there some type of restriction in the PAM files that needs modification?

    Thanks.

  35. MH’s avatar

    Scott,

    To add to my earlier statement I also found that I can’t do a getent passwd ADAccount on this machine. It just returns the prompt. However I am able to login to the system and function.

  36. MH’s avatar

    Scratch my last two posts… my apologies. I modified smb.conf and changed “winbind use default domain” from false to yes and things are now working. I have found that I can modify /etc/group and put an AD user account on wheel but when I add a AD group there it doesn’t let me su. I’ll keep chugging away and my apologies for the previous posts.

  37. Senad’s avatar

    I have ES 4 working with Active Directory 2003. Users can log in and change passwords but the issue I have is that if I disable an account from Active Directory, the user is still able to login. I think it is caching the user profile. Also the user can log ijn with only the first 8 characters of his password. If i try to change a password on a disabled account is says passwd: Authentication token manipulation error

  38. David’s avatar

    I am usng RHEL AS 4.0 to authenticate with AD. I get the following message when I use kinit – username: “KDC reply did not match expectations while getting initial credentials”. Below are my conf files modified according to Scot’s blog. Domain is test.net. I just want to get basic authentication between the linux and AD box. Any help is appreciated.
    —————————————-
    Krb.5.conf
    [logging]
    default = FILE:/var/log/krb5libs.log
    kdc = FILE:/var/log/krb5kdc.log
    admin_server = FILE:/var/log/kadmind.log

    [libdefaults]
    default_realm = test.net
    dns_lookup_realm = true
    dns_lookup_kdc = true

    #[realms]
    #EXAMPLE.COM = {
    # kdc = kerberos.example.com:88
    # admin_server = kerberos.example.com:749
    # default_domain = example.com
    # }

    [domain_realm]
    .test.net = test.net
    test.net = test.net

    [kdc]
    profile = /var/kerberos/krb5kdc/kdc.conf

    [appdefaults]
    pam = {
    debug = false
    ticket_lifetime = 36000
    renew_lifetime = 36000
    forwardable = true
    krb4_convert = false
    }
    —————————————–
    Ldap.conf
    host 172.20.0.20
    base dc=test,dc=net
    uri ldap://servertest.test.net
    binddn ldap@test.net
    bindpw Test12345
    scope sub
    ssl no
    pam_filter objectClass=User
    nss_base_passwd dc=test,dc=net?sub
    nss_base_shadow dc=test,dc=net?sub
    nss_base_group dc=test,dc=net?sub
    nss_map_objectclass posixAccount user
    nss_map_objectclass shadowAccount user
    nss_map_objectclass posixGroup group
    nss_map_attribute gecos name
    nss_map_attribute homeDirectory unixHomeDirectory
    nss_map_attribute uniqueMember member
    —————————————————————————
    system-auth
    #%PAM-1.0
    # This file is auto-generated.
    # User changes will be destroyed the next time authconfig is run.
    auth required /lib/security/$ISA/pam_env.so
    auth sufficient /lib/security/$ISA/pam_unix.so likeauth nullok
    auth sufficient /lib/security/$ISA/pam_ldap.so use_first_pass
    auth required /lib/security/$ISA/pam_deny.so

    account required /lib/security/$ISA/pam_unix.so broken_shadow
    account sufficient /lib/security/$ISA/pam_succeed_if.so uid

  39. slowe’s avatar

    David,

    The first thing that jumps out at me is that your Kerberos realms (in the [domain_realm] section of krb5.conf) need to be specified in UPPERCASE. They are case-sensitive, and only UPPERCASE realms are supported.

    You didn’t specify whether “gentent passwd” or “getent group” worked…do they? This will help us determine if the issue lies solely with Kerberos, or if there are other issues as well.

  40. Ken’s avatar

    Scott,

    Your site is great. I have been able to setup Linux using Red Hat ES 4 against W2K3 AD R2 using TLS and kerbos. Now I am trying to figure out how to get sudo to use LDAP. I have checked all files in /etc/pam.d/ like sudo, su, sshd, login and they all point to system-auth, which is configured to use krb5. I would like to have a sudo group in LDAP that I can use across many servers. Have you got this to work? Is this possibile? Thanks!

  41. slowe’s avatar

    Ken,

    If your nsswitch.conf is already configured to use LDAP, and nss_ldap (via /etc/ldap.conf) is working, then sudo should pick that stuff up as well. What kinds of errors are you experiencing? Anything in the logs?

  42. KD’s avatar

    Hi Scott,

    As per your instruction I have Set the my AD 2003 R2 server and Centos4.5 and 5.0

    I can authentication, home directory are mapped properly. Everything is working fine.

    One of our engineers is doing some testing and we are facing disconnects in between AD and centos.

    Here is the log message:

    Oct 25 18:01:20 nscd: nss_ldap: could not get LDAP result – Can’t contact LDAP server
    Oct 25 18:01:20 nscd: nss_ldap: could not get LDAP result – Can’t contact LDAP server
    Oct 25 19:03:21 nscd: nss_ldap: reconnected to LDAP server ldap://192.168.3.4 after 1 attempt
    Oct 25 20:01:01 nscd: nss_ldap: could not get LDAP result – Can’t contact LDAP server
    Oct 25 22:01:10 last message repeated 2 times
    Oct 26 00:01:12 last message repeated 2 times
    Oct 26 03:01:01 last message repeated 2 times
    Oct 26 05:01:04 last message repeated 2 times
    Oct 26 07:01:06 last message repeated 2 times
    Oct 26 07:01:06 nscd: nss_ldap: could not get LDAP result – Can’t contact LDAP server

    I don’t know why it should disconnect it in between once it is successfully authenticated.

    Any help would be great.

    Thanks
    KD

  43. Ken’s avatar

    Hi Scott,

    I am getting errors pointing to that it is trying to authenticate sudo locally. I log in as my AD user and that works. I then try to sudo and i get “sudo: uid 10000 does not exist in the passwd file!”

    /var/log/messages:
    Nov 13 15:03:48 linux01 sshd(pam_unix)[17194]: session opened for user root by root(uid=0)
    Nov 13 15:03:57 linux01 sshd: pam_krb5[17226]: authentication succeeds for ‘khenry’ (khenry@DEV.ROOT)
    Nov 13 15:03:57 linux01 sshd(pam_unix)[17228]: session opened for user khenry by (uid=0)
    Nov 13 15:04:51 linux01 sudo: 10000 : uid 10000 does not exist in the passwd file! ; TTY=pts/1 ; PWD=unknown ; USER=root ; COMMAND=su

    /var/log/secure:
    Nov 13 20:03:57 linux01 sshd[17227]: Accepted password for khenry from ::ffff:172.16.112.57 port 4571 ssh2
    Nov 13 15:03:57 linux01 sshd[17226]: nss_ldap: reconnecting to LDAP server…
    Nov 13 15:03:57 linux01 sshd[17226]: nss_ldap: reconnected to LDAP server after 1 attempt(s)

    nsswitch.conf
    passwd: files ldap compat
    shadow: files ldap compat
    group: files ldap compat
    hosts: files dns
    bootparams: files
    ethers: files
    netmasks: files
    networks: files
    protocols: files
    rpc: files
    services: files
    netgroup: files
    publickey: files
    automount: files
    aliases: files

    /etc/ldap.conf
    host dev-dc01.dev.root
    uri ldap://dev-dc01.dev.root/
    binddn CN=linuxbind,CN=Users,DC=dev,DC=root
    bindpw D0ughB0y
    bind_policy soft
    scope sub
    ssl start_tls
    pam_filter objectClass=User
    pam_groupdns cn=Acces,ou=Users,dc=dev,dc=root
    pam_member_attribute member
    pam_password ad
    nss_base_passwd cn=Users,dc=dev,dc=root
    nss_base_shadow cn=User,dc=dev,dc=root
    nss_base_group cn=Users,dc=dev,dc=root
    nss_map_objectclass posixAccount user
    nss_map_objectclass shadowAccount user
    nss_map_objectclass posixGroup group
    nss_map_attribute gecos cn
    nss_map_attribute homeDirectory unixHomeDirectory
    nss_map_attribute uniqueMember member
    tls_checkpeer yes

    Thanks for any help…

  44. slowe’s avatar

    Ken,

    Is your PAM configuration using something different for sudo than the default? Check /etc/pam.d for a sudo file and see how that compares to the system-auth file or its equivalent.

  45. Ken’s avatar

    That file points to system-auth too.

    auth required pam_stack.so service=system-auth
    account required pam_stack.so service=system-auth
    password required pam_stack.so service=system-auth
    session required pam_limits.so

    I am running out of ideas.

  46. slowe’s avatar

    Ken,

    Let’s see the system-auth file…maybe that will shed some light on the issue.

  47. Ken’s avatar

    here ya go:

    auth required /lib/security/$ISA/pam_env.so
    auth sufficient /lib/security/$ISA/pam_unix.so likeauth nullok
    auth sufficient /lib/security/$ISA/pam_krb5.so
    #auth sufficient /lib/security/$ISA/pam_ldap.so use_first_pass
    auth required /lib/security/$ISA/pam_deny.so

    account sufficient /lib/security/$ISA/pam_krb5.so
    #auth sufficient /lib/security/$ISA/pam_ldap.so use_first_pass
    account required /lib/security/$ISA/pam_unix.so
    account sufficient /lib/security/$ISA/pam_succeed_if.so uid

  48. slowe’s avatar

    Ken, what about your /etc/sudoers file? If you don’t want to post it here, just e-mail it to me.

  49. Ken’s avatar

    Its ok to post it. Its pretty generic. Linux group is in AD. I think I did try putting the the full DN path too.

    # User privilege specification
    root ALL=(ALL) ALL

    # Uncomment to allow people in group wheel to run all commands
    #%wheel ALL=(ALL) ALL
    %Linux ALL=(ALL) ALL
    # Same thing without a password
    #%wheel ALL=(ALL) NOPASSWD: ALL

  50. Gianluca’s avatar

    Hi Scott,

    I am working at integrating win and *nix in a scenario where there are three domains in a domain three with w2k3R2. I am using kerberos+ldap and i can fetch users id and groups for all three domains, the problem is that i can only authenticate those in the kerberos default domain.
    I know it is possible to set-up cross realm authentication but i’m kind of lost. Have you got any experience with cross realm?

    thxs,
    Gianluca

· 1 · 2 · 3 ·