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: , , , , , , ,

Scott,

Couple of questions:

1. In ldap.conf you say “binddn ldap@example.com” should I interpret that to be “binddn myusername@example.com“, where “myusername” is the single user account that I created early on in the section “Finally, you’ll also need to create an account in Active Directory that will be used to bind to Active Directory for LDAP queries. “?

Is it possible for you to post these instructions with colored text highlighting values that are specific to our environments? (I’m just a dumb windows admin ;) trying to play in a linux world.

2. Does the “pam_mkhomedir.so” go in the system-auth file? And if so what does it look like?

3. Any chance of having you post your actual configuration files, I’m using Centos 4.3 as well.

Thank you very much, I don’t have this working yet, but your blog has been the most helpful thing I’ve found around.

Ron

Ron,

1. Yes, you are exactly correct–change that information to match the username that was created earlier for the purpose of binding to Active Directory. So, if your username is ldapbind and your domain is example.com, then the UPN (User Principal Name) would be ldapbind@example.com, and that’s what you would put into /etc/ldap.conf for the binddn parameter.

2. Yes, it goes in the system-auth file. Try something like this (edit the path appropriately–just make it match everything else listed in the file):

session required /lib/security/pam_mkhomedir.so skel=/etc/skel umask=0022

3. Send me an e-mail (scott dot lowe at scottlowe dot org) so that I can verify your e-mail address, and I’ll send you a copy of my config files (in plain text, so I can’t color code things). I’ll try to make it clear what you’ll need to supply in the files I send you.

I’m glad you find the site helpful.

I have tried:

ktpass -princ HOST/linux01.example.com@EXAMPLE.COM -mapuser EXAMPLE\LINUX01$ -crypto DES-CBC-MD5 +DesOnly -pass * -ptype KRB5_NT_SRV_HST -out c:\krb5.keytab

and got the following output:

Targeting domain controller: myAD.example.com
Successfully mapped HOST/linux01.example.com to LINUX01$.
WARNING: Account LINUX01$ is not a user account (uacflags=0×1021).
WARNING: Resetting LINUX01$’s password may cause authentication problems if LINUX$ is being used as a server.

Reset LINUX$’s password [y/n]? Y
Key created.
Output keytab to c:\krb5.keytab:
Keytab version: 0×502
keysize 59 HOST/linux01.ruckh.net@RUCKH.NET ptype 3 (KRB5_NT_SRV_HST) vno 2 etype 0×3 (DES-CBC-MD5) keylength 8 (0xc151ab730bbf917f)

Account LINUX01$ has been set for DES-only encryption.

I copy the keytab file over to linux server, but get this in /var/log/messages:

TGT failed verification using key for ‘HOST/linux01.example.com@example.com’

Something tells me the keytab file is not working correctly.

If I set validate to false in the pam section of /etc/krb5.conf user authentication works and no error in the /var/log/messages.

I can run kinit username; where user is an AD user. After successfully typing password I am returned to a shell prompt with no errors. I assume the kerberos stuff is working. After running kinit I can run klist and display the which was generated from the kinit command.

Any suggestions?

Thanks.

Scott,

I know this sounds crazy, but try that command again with the password on the command line, instead of using “pass *”. I have seen references that ktpass.exe will output the keytab with a key version number one lower than what will be set in Active Directory. In your example, the key version number (kvno) in the keytab is 2 (this is shown in the ktpass.exe output). You can check the value of the msDS-KeyVersionNumber attribute on the account to see if it matches the kvno shown in the ktpass.exe output (you can also use klist -keK to print the kvno in the keytab on the Linux side). If the two values don’t match, then TGT validation will fail. Try the command again with the password on the command line, then compare the value of the kvno in the keytab against Active Directory. That should help matters.

Great set of instructions here. Thanks for posting. I’ve found this really helpful.

1. I’m getting the same results for the post above. I am able to authenticate with ‘validate=false’. However, when I set ‘validate=true’, authentication completes but the TGT validation fails — thus rejecting the login. I’ve verified that the key version number is the same per the output of ktpass and klist -keK.

2. Is it necessary for the user to be listed in /etc/passwd in order for them to log in? I thought this was the whole purpose of this exercise…to stop making user accounts on individual boxes. If I remove a user from /etc/passwd, they are no longer able to log into the individual box. If so, how do you handle a fairly large environment?

3. The name from the gecos field does not show up. Is there a way to query this under AD to find out what attribute it stores the name under?

TIA.

I ended up using the following batch file to create keytab file:

@echo off

:: %1 is the username
:: %2 is the realm

ktpass -princ nssldap/%1@%2 -mapuser %1@%2 -pass secret -out %1.keytab

In this case my AD account is a user account and not a machine account.

Ok, I finally have an acceptable configuration that is working. It uses secure communication between Linux boxes and LDAP server, and user is able to change password from Linux or Windows. Once I get all the chicken scratches organized into some sensible documentation I will post the final configuration here.

Thanks for all the feedback.
Scott

Ron, note that the service principal name is case-sensitive, so be sure to use the right case on the Windows box when running the ktpass.exe command. Also, it is not necessary to maintain local accounts; that’s the point behind configuring /etc/nsswitch.conf and /etc/ldap.conf, so that the Linux box can retrieve account information from Active Directory.

Scott, I’m glad to hear that it’s finally working. I’m curious about your use of the service principal name in the ktpass.exe command–”nssldap/username@REALM”–where did you turn up that information, and does it work? I’d love to see your final config. Feel free to e-mail me the config at scott dot lowe at scottlowe dot org.

Ryan,

With Win2k3 R2 there is a gecos field but it is unpopulated. If you want to use the gecos field in AD open up adsiedit go to the user and populate the gecos field to be whatever you want it to be. Otherwise, set the `nss_map_attribute gecos’ value (in your /etc/ldap.conf file) to whatever AD field you would like to use.

Scott,
My one problem I am having right now is that if I check the must change password at next login in and then try logging into a linux box, I can not change the password. I am prompted to change the password, but something not workie so good. If that value is unchecked the user can log in, issue the passwd command, and can successfully change password. Once I get everything working as expected, I definitely plan on posting final configs.

This wordpress blog has been the best resource for me, so hopefully I can also share my failures and successes in hopes that someone can find it useful.

Ryan,

Scott’s correct–you can populate gecos yourself with ADSI Edit. Or, you can edit /etc/ldap.conf and change the nss_map_attribute command to map gecos to cn; that will show the name.

Scott,

The problem you’re having with initial password changes doesn’t surprise me–I’ve seen the same thing in other environments (Novell NetWare, for example). I think it’s a Windows proprietary limitation, and would not be surprised if there wasn’t a workaround. I’m really glad that this weblog has been helpful to you.

I tried to use your TGT authentication steps once again, but can not get it to work.

I created a Computer account in Active Directory (VMLNX01). I enabled: Assign this computer account as a pre-Windows 2000 computer.

I ran the following command a received the following output:

ktpass -princ HOST/vmlnx01.ruckh.net@RUCKH.NET -mapuser RUCKH\VMLNX01$ -crypto DES-CBC-MD5 +DesOnly -pass secret -ptype KRB5_NT_SRV_HST -out c:\vmlnx01.keytab

Targeting domain controller: gemneyedc.ruckh.net
Successfully mapped HOST/vmlnx01.ruckh.net to VMLNX01$.
WARNING: Account VMLNX01$ is not a user account (uacflags=0×1021).
WARNING: Resetting VMLNX01$’s password may cause authentication problems if VMLNX01$ is being used as a server.

Reset VMLNX01$’s password [y/n]? y
Key created.
Output keytab to c:\vmlnx01.keytab:
Keytab version: 0×502
keysize 59 HOST/vmlnx01.ruckh.net@RUCKH.NET ptype 3 (KRB5_NT_SRV_HST) vno 2 etype 0×3 (DES-CBC-MD5) keylength 8 (0×86f176c88cfde93e)

Account VMLNX01$ has been set for DES-only encryption.

I copied that file to the Linux server and copied it to the /etc/krb5.keytab file.

Although I can run kinit with a user and get a ticket, when I try to login I get the following error in /var/log/messages:

TGT failed verification using key for ‘HOST/vmlnx01.ruckh.net@RUCKH.NET’

Am I using the correct syntax?

As I have already posted, when I create a user account and run the following batch file to create keytab file everything works.

@echo off

:: %1 is the username
:: %2 is the realm

REM change the ‘*’ character to the real password in case you want to loop this.
REM else you will be prompted for the password.

ktpass -princ nssldap/%1@%2 -mapuser %1@%2 -pass secure -out %1.keytab

I am trying to distinguish the difference between your method and others I have come across.

Also, I am trying to understand why what works for you is not working for me.

Do you run kinit for the host in the keytab file?

When I am using the other method I have a crontab entry that looks like the following:

/usr/kerberos/bin/kinit -k nssldap/krb5_vmlnx01 -c /tmp/krb5cc_0 2>&1 > /dev/null

I am just trying to understand this step so I can make some decisions on which method makes more sense.

Your input is appreciated.

Thanks.
Scott

Scott,

The only other thing I can suggest is to try the command “kinit -k HOST/vmlnx01.ruckh.net@RUCKH.NET” and see if you are issued a TGT without being prompted for a password. Note that a straight “kinit -k” may still fail, but that shouldn’t be an issue. If specifying the SPN works with the kinit command, then TGT validation should work. If not, then you still have issues with the keytabs. One interesting point: I have found that if the key version number (kvno) is not 3, then things act strangely. I don’t know why that is, but I know that it almost always works when the kvno is 3 and the SPN is correct (including case).

There should not be a need for a kinit command in the crontab.

Also, try changing to a user account as I describe in some of the later Kerberos-related articles. I discussed computer accounts vs. user accounts in an article I posted earlier today at http://blog.scottlowe.org/2006/08/21/native-kerberos-authentication-with-ssh/.

Hope this helps,
Scott

The output below shows KVNO as 2

ktutil: l
slot KVNO Principal
—- —- ———————————————————————
ktutil: rkt /etc/krb5.keytab
ktutil: l
slot KVNO Principal
—- —- ———————————————————————
1 2 HOST/vmlnx01.ruckh.net@RUCKH.NET

kinit -k HOST/vmlnx01.ruckh.net@RUCKH.NET

kinit(v5): Preauthentication failed while getting initial credentials

Adding -kvno 3 to the command line did not help.

This article shows yet another syntax for creating UNIX keytab file:

http://support.microsoft.com/default.aspx?scid=kb;en-us;324144

I would rather have a machine account, rather then a user account if possible.

Thanks
Scott

Scott,

Thanks for the tips. I have everything working except the TGT validation. I’m going to give you an example here of my environment in hopes that you can pin point the mistake I’m making. For security reasons I have masked the real domain.tld. It just is obviously not working ;-)

The line below is one long line. I’ve made sure that the SPN is correct, including case:

C:\Documents and Settings\Administrator\Desktop>ktpass -princ HOST/devnull.ad.mydomain.net@AD.MYDOMAIN.NET -mapuser AD\DEVNULL$ -crypto DES-CBC-MD5 +DesOnly -ptype KRB5_NT_SRV_HST -kvno 3 -pass secure -out devnull.keytab

I’ve also forced the version number to ‘3′ as you’ve stated that its only worked when the value equals 3.

I then copy the devnull.keytab over to the linux (CentOS 4.3) box via SCP from my DC.
The devnull.keytab file gets moved over to /etc/krb5.keytab.

klist -keK shows:

Keytab name: FILE:/etc/krb5.keytab
KVNO Principal
—- ————————————————————————–
3 HOST/devnull.ad.mydomain.net@AD.MYDOMAIN.NET (DES cbc mode with RSA-MD5) (0×612683c7c85b26f8)

My /etc/ldap.conf shows:

host 192.168.0.200
base dc=ad,dc=mydomain,dc=net
uri ldap://192.168.44.200/
binddn ldap@ad.mydomain.net
bindpw abc123!@
scope sub
ssl no
pam_filter objectClass=User
nss_base_passwd dc=ad,dc=mydomain,dc=net?sub
nss_base_shadow dc=ad,dc=mydomain,dc=net?sub
nss_base_group dc=ad,dc=mydomain,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

My /etc/krb5.conf has:

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

[libdefaults]
default_realm = AD.MYDOMAIN.NET
dns_lookup_realm = true
dns_lookup_kdc = true

[domain_realm]
.ad.mydomain.net = AD.MYDOMAIN.NET
ad.mydomain.net = AD.MYDOMAIN.NET

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

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

NOTE: The proper SRV records exist in dns.

Now when I get validate=true, I get the following in my /var/log/secure file:

Aug 22 13:54:47 devnull login: pam_krb5[8573]: configured realm ‘AD.MYDOMAIN.NET’
Aug 22 13:54:47 devnull login: pam_krb5[8573]: flags: forwardable
Aug 22 13:54:47 devnull login: pam_krb5[8573]: flag: no ignore_afs
Aug 22 13:54:47 devnull login: pam_krb5[8573]: flag: user_check
Aug 22 13:54:47 devnull login: pam_krb5[8573]: flag: no krb4_convert
Aug 22 13:54:47 devnull login: pam_krb5[8573]: flag: validate
Aug 22 13:54:47 devnull login: pam_krb5[8573]: flag: warn
Aug 22 13:54:47 devnull login: pam_krb5[8573]: ticket lifetime: 36000
Aug 22 13:54:47 devnull login: pam_krb5[8573]: renewable lifetime: 36000
Aug 22 13:54:47 devnull login: pam_krb5[8573]: banner: Kerberos 5
Aug 22 13:54:48 devnull login: pam_krb5[8573]: ccache dir: /tmp
Aug 22 13:54:48 devnull login: pam_krb5[8573]: keytab: /etc/krb5.keytab
Aug 22 13:54:48 devnull login: pam_krb5[8573]: called to authenticate ‘johndoe’
Aug 22 13:54:48 devnull login: pam_krb5[8573]: authenticating ‘johndoe@AD.MYDOMAIN.NET’
Aug 22 13:54:48 devnull login: pam_krb5[8573]: trying previously-entered password for ‘johndoe’
Aug 22 13:54:48 devnull login: pam_krb5[8573]: authenticating ‘johndoe@AD.MYDOMAIN.NET’ to ‘krbtgt/AD.MYDOMAIN.NET@AD.MYDOMAIN.NET’
Aug 22 13:54:48 devnull login: pam_krb5[8573]: krb5_get_init_creds_password(krbtgt/AD.MYDOMAIN.NET@AD.MYDOMAIN.NET) returned 0 (Success)
Aug 22 13:54:48 devnull login: pam_krb5[8573]: validating credentials
Aug 22 13:54:48 devnull login: pam_krb5[8573]: TGT failed verification using key for ‘HOST/devnull.ad.mydomain.net@AD.MYDOMAIN.NET’
Aug 22 13:54:48 devnull login: pam_krb5[8573]: got result 0 (Success)
Aug 22 13:54:48 devnull login: pam_krb5[8573]: authentication fails for ‘johndoe’ (johndoe@AD.MYDOMAIN.NET): Authentication failure (Success)
Aug 22 13:54:48 devnull login: pam_krb5[8573]: pam_authenticate returning 7 (Authentication failure)
Aug 22 13:54:50 devnull login: FAILED LOGIN 1 FROM (null) FOR johndoe, Authentication failure

Now if I set validate=false, logins will work just fine. Thoughts, ideas? =)

Thanks.

Ryan

I realized I made a typo in the above command, using ktpass.

It should read:

C:\Documents and Settings\Administrator\Desktop>ktpass -princ HOST/ad.mydomain.net@AD.MYDOMAIN.NET -mapuser AD\DEVNULL$ -crypto DES-CBC-MD5 +DesOnly -ptype KRB5_NT_SRV_HST -kvno 3 -pass secure -out devnull.keytab

Thanks again.

Ryan

I wonder my problem is related to this:

http://support.microsoft.com/default.aspx?scid=kb;en-us;919557&sd=rss&spid=3198 ?

It looks like the exact problem I am having.

It is still strange that this bat file works with a user account:

@echo off

:: %1 is the username
:: %2 is the realm

REM change the ‘*’ character to the real password in case you want to loop this.
REM else you will be prompted for the password.

ktpass -princ nssldap/%1@%2 -mapuser %1@%2 -pass SECRET -out %1.keytab

Scott,

Try using all lowercase with your service principal name (except for the realm, of course). I initially suspected that it might require an uppercase HOST instance, but further testing showed that I can validate the TGT with a lowercase host instance. Also, the hotfix you mentioned would support the fact that the keytab for computer accounts is generated incorrectly, but the keytab for user accounts is generated correctly–exactly the situation you describe involving your batch file (which works). I’d love to hear if this hotfix helps address the situation. And, even though you want to use a computer account, just try it with a user account and see if the problem persists.

Ryan,

Try re-generating the keytab using all lowercase, and try with a user account instead of a computer account. And, unless I’m missing something, your first ktpass.exe command is correct–you need the fully qualified domain name of the host, i.e., devnull.ad.mydomain.net, not just the domain name itself. The realm will be the domain name in UPPERCASE.

Yes, the Microsoft hotfix fixed the problem. Case sensitivity was not the problem (I had actually already tried your suggestion earlier). If you remember, the usage of SSL is where our environments are different. Sure enough that bug in ktpass was the difference. I had been banging my head on this one for a few days.

Now, if I can get the “User must change password at next logon” working from the Linux side I will be satisfied. That is really something that is bugging me. I can set the password using the passwd command, but not at login. I am going to have to trace some packets and see what the difference is. The same prompts are displayed, but obviously something is different.

I may be attempting the impossible, but I have not yet given up the fight.

Thanks.
Scott

The main problem with setting the, “User must change password at next login”, is that with this setting enabled the user is not able to bind to Active Directory (LDAP), and therefore is not able to change their password.

When this setting is disabled, the user can bind to LDAP and the password can be changed.

The reason this would be a great feature is because not all users actually have a means of changing their password with native Windows tools. If this is truly a single-sign-on solution where the user it logging into Windows and can change AD password it is not a big deal. Unfortunately that luxury is not true for all environments.

I think I am about to take off the gloves and declare defeat.

Scott

If I use

password sufficient /lib/security/$ISA/pam_krb5.so debug minimum_uid=499 use_authok

in /etc/pam.d/system-auth

and turn off TGT validation in /etc/krb5.conf

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

then I am able to reset passwords from Linux machines. I can reset passwords using passwd, and can enable “User must change password at next logon” in Active Directory, and force a password a change. It all works fine.

If validate is left to be true, then a pam_krb5 error message is logged in /var/log/messages

pam_krb5[31327]: TGT failed verification using key for ”

Which is strange because that same key was successful seconds earlier when authenticating the users account for logging into the system.

Why would the keytab be successful for authorization but not successful when used with the passwd command?

Scott,

Two thoughts:

1. First, try using kpasswd instead of just passwd. It seems like I recall seeing that you needed to use kpasswd (the Kerberos passwd utility) instead of straight passwd.

2. Second, it may be possible that the password change is using a different SPN than the login process, i.e., it may not be using host/fqdn@REALM, but a different SPN entirely; hence, TGT validation fails. I don’t know for sure.

I have not extensively tested changing the passwd from the Linux side, but I am scheduled to be back in my office tomorrow and I’ll have a look at it in the lab to see if I find anything.

kpasswd works fine from a shell prompt.

Unfortunately, when logging in through ssh, and when password is expired (or forced to change at first login), `passwd’ is automatically called during the login process.

Is there a way to change that default behavior and have kpasswd called instead for only kerberos logins?

I was wondering how significant the Service Principal Name is with this whole process. As I was able to login with at least three different variations of the SPN and keytab file, I was making the assumption that it was not that important. Although the error suggests otherwise.

Scott

I am using Openldap client to authenticate Linux servers to my AD implementation. I can authenticate, but I cannot use passwd to set the password. The error message is as follows:

-bash-3.00$ passwd
Changing password for user scott.
Enter login(LDAP) password:
New UNIX password:
Retype new UNIX password:
LDAP password information update failed: Can’t contact LDAP server
00002077: SvcErr: DSID-03190DC8, problem 5003 (WILL_NOT_PERFORM), data 0

passwd: Permission denied
-bash-3.00$

If anyone knows what is the cause of this, please let me know. IT appeard to be coming back from my 2003 AD Domain Controller.

Steve,

I would guess you are using pam_ldap and nss_ldap for authentication and name service lookups, right? Send me your pam configuration and your ldap.conf file, and I’ll see what I can do to help troubleshoot the issue.

How do you control access?

For example, say you have 3 groups (A, B, and C). Users of Group A should have access to all servers, Group B should have access to only a few servers, and Group C will have access to a few servers.

Obviously each server’s ldap.conf file could contain configurations using different AD containers to limit access, but how would you handle access for the below situation?

Severs: Groups that have access

Server 1: Group A, Group B, and Group C
Server 2: Group A
Server 3: Group A and Group C

Thanks.
Scott

Scott,

With regards to access control, I’d have a look at the “LDAP-Based Access Control” posting I wrote at http://blog.scottlowe.org/2006/09/08/ldap-based-access-control/ (I posted this specifically because of some similar questions). Hopefully that would address your concerns. The right combination of security groups with the appropriate ldap.conf on each host should do exactly what you need. The real question (I have not yet had the opportunity to test this) is to see if nested groups work, i.e., create a Domain Local group for each host, then place Global groups into the appropriate Domain Local groups for the hosts to which they should be allowed access. I don’t know if that would work, but it would certainly give more flexibility.

I looked at your other blog entry, but I do not think that is what I need. I knew you could already do that. I am trying to accomplish exactly what you have stated above.

Have a domain local group that is specific to a server, and a global group that is more generic that can be added to each domain local group.

As an alternative can you have multiple pam_groupdn entries or something like that?

I guess I will have to do some testing. As you have already done some work with this, I thought you already had a working solution in your bag of tricks.

Thanks.
Scott

Scott,

As far as I know, multiple pam_groupdn entries are not allowed. I’ll be back in the lab on Monday, so I’ll try some nested group testing then and see what I can discover.

I’ve found a couple of sites that talk about the kvno matching what is in AD. Not being a windows guy, I haven’t figured out how to find the “msDS-KeyVersionNumber” attribute in AD. I’ve loaded an LDAP browser and have searched under “CN=mymapuser,CN=Users,DC=mydomain,dc=com” and I just don’t see the attribite there… Am I looking in the wrong place?

disregard… I just found the adsiedit tool.

That’s exactly where I was going to direct you. For getting detailed information out of Active Directory, ADSIEdit is your best friend.

I am using Windows 2003 R2 and CentOS 4.3
My ldap.conf is not mapping over the password somehow! Please point me in the right direction.

— /etc/ldap.conf —–
nss_base_passwd dc=test,dc=local?sub
nss_base_shadow dc=test,dc=local?sub
nss_base_group dc=test,dc=local?sub
nss_map_objectclass posixAccount user
nss_map_objectclass shadowAccount user

#getent passwd
test01:x:10006:10004:test01:/home/test01:/bin/sh
test02:x:10003:10004:test02:/home/test02:/bin/sh
test03:x:10004:10004:test03:/home/test03:/bin/sh
test04:x:10005:10004:test04:/home/test04:/bin/sh
#getent passwd
test01:x:::::::0
test02:x:::::::0
test03:x:::::::0
test04:x:::::::0

sshd[4954]: pam_ldap: error trying to bind as user “CN=test01,OU=UNIX-Users,OU=UNIX-OU,DC=test,DC=local” (Invalid credentials)

It looks like you have an error in the /etc/ldap.conf where you specify the account that will be used to bind to Active Directory. Double-check your binddn and bindpw settings in the file and make sure that they are correct and match a valid account in Active Directory. Are you using Kerberos for authentication? Does kinit username@domain.com (substituting correct values here, of course) work? Keep in mind that the solution, as presented in this article, uses Kerberos for authentication and LDAP for name service lookups.

Scott,

I’m glad I found these instructions; it’s just what I was looking for. I have a few questions.

1. You need to be a Schema Admin to extended the schema (obviously). You also need to be a Schema Admin to install the Identity Management pieces because it modifies a few entries in the schema to display the UNIX tab in ADUC. Now, you say you need to install those components “in order to be able to actually set those attributes”. Could you just register the nisprop.dll and leave it at that? Registering that dll will allow those tabs to be displayed.
2. After the components get installed, I noticed the “Server for NIS” service is set to disabled. Do you need to turn that on for this to work? If not, do you really need to install the components if you can register the dll (See #1 above)?
3. What ports would have to be open on a fw to allow this communication to work? I assume the Kerberos port but what about some of the other ports (NetBIOS, LDAP, DNS, etc). Or, another way of putting this is, is this any different from a Windows box trying to log in?

Thanks.

Andy,

Good questions. I don’t recall having to be a Schema Admin to install Server for NIS in Windows Server 2003 R2, because the partially RFC 2307-compliant schema is already present. It’s been a while, so I could be wrong here. I suppose that registering nisprop.dll would also work; it would most certainly work on administrative workstations that need the ability to set Unix attributes.

There is no need to actually run the NIS server.

This communication is standards-based: UDP port 88 for Kerberos (sometimes TCP port 88, depending upon the Kerberos implementation) and TCP port 389 for LDAP (636 if you are using LDAP over SSL). I would consider this to be very different than a Windows box trying to get in; there’s no RPC or NetBIOS traffic involved.

Can you tell me if authenticating an Active Directory user on a RHEL4 client to a 2003R2 server using this method will put an entry in the Windows Security Event Log that specifically identifies the user logging in? I tried to use Identity Mgmt for UNIX for this, but it shows the user authenticating as the domain controller, not the user. I guess this happens since the NIS server is on the domain controller.
I need to have an accurate Security Event Log in this regard.

Thanks for any help.

RS,

Yes, event log entries will be generated that identify the user. Refer to http://blog.scottlowe.org/2006/10/23/event-logging-in-ad-integration-scenarios/ for more information.

Thanks,
Scott

Scott!

You don’t have to install the “Server for NIS” component to get the UNIX Attributes tab.

All you have to do is install the Identity Management Unix tools from the X:\ADMIN\IDMU.exe setup file.

This makes a simpler process and you aren’t installing a service you don’t need.

Please note that installing just the Administration Components under AD services… Identity Management for Unix in the Windows Componants Wizard does not do the same thing.

Scott, you mentioned that it is
“necessary to set those attributes using the Active Directory Users and Computers console before logins from Linux will work”

Do you know if the tab does anything special?

I was thinking about programatically updating the Attributes due the need of updating thousands of users.

Awesome info. I’m loving your interoperability writeups.

Gabriel,

The tab simply offers a UI to the underlying AD attributes. You can most definitely populate these attributes programmatically or via a script instead of using the UI. Use ADSI Edit or a similar tool and look for msSFU30NisDomain, uid, uidNumber, gidNumber, unixHomeDirectory, loginShell, etc. You can set them however you’d like.

Also, thanks for the update regarding the availability of the UNIX attributes tab. In some cases, the installation of the NIS server may be helpful (for example, my article regarding NFS and automounts needs NIS). I’ve also heard that registering nisprop.dll also makes the UNIX Attributes tab visible as well, so this may be yet another approach.

Hope this helps!

Scott

Gabriel and Scott,

I played around with this alot and yeah, you can run the IDMU.exe or register the nisprop.dll. The thing that I got hung up on was that you need to be a Schema Admin when you run the exe or register the dll. If you aren’t, the tabs won’t show up.

Andy

I’m trying to set up a RH ES 4 server so I can log into a W2K3 domain. I followed all the instructions above (including running authconfig) and I can:
1. Issue the id user1 command and get a valid uid.
2. Issue the klist -keK command and I see the Kerberos ticket
3. Issue the kinit user1 command and log in
4. From the login screen, I can log into the machine using a Windows domain account.
5. Issue the kpasswd command and change the user’s password.

So, it all seems to work. However, I don’t understand these errors; especially the middle one where it says “Authentication failure (Success)”. Is it a failure or a success?

Nov 21 13:55:50 test-vlinux1 unix_chkpwd[3628]: password check failed for user (user1)
Nov 21 13:55:50 test-vlinux1 gdm(pam_unix)[3449]: authentication failure; logname= uid=0 euid=0 tty=:0 ruser= rhost= user=user1
Nov 21 13:55:50 test-vlinux1 gdm-binary[3449]: pam_krb5[3449]: TGT failed verification using key for ‘HOST/test-vlinux1.domainname.local@DOMAINNAME.LOCAL’
Nov 21 13:55:50 test-vlinux1 gdm-binary[3449]: pam_krb5[3449]: authentication fails for ‘user1′ (user1@DOMAINNAME.LOCAL): Authentication failure (Success)
Nov 21 13:55:51 test-vlinux1 gdm(pam_unix)[3449]: session opened for user user1 by (uid=0)
Nov 21 13:55:54 test-vlinux1 gconfd (user1-3693): starting (version 2.8.1), pid 3693 user ‘user1′

Can anyone decipher these for me? Or at least point me in the right direction. Thanks.

Andy

PS. Scott - Sorry about the flood a few weeks ago. Didn’t sound like fun.

Andy,

I could certainly see needing to be a Schema Admin to run the IDMU.exe, since it may be that which extends the schema to include the Unix-specific attributes. But if the schema was already extended, registering nisprop.dll shouldn’t require Schema Admin privileges. However, registering nisprop.dll without first having the schema extended may produce the results you describe where the tab just doesn’t appear (because there are no attributes in Active Directory to display on the tab).

Regards,
Scott

Andy,

No, the flood was definitely not fun. :)

The error here is in the TGT validation, which is failing and causing the entire authentication process to fail (despite the cryptic wording in the logs). Have a look at http://blog.scottlowe.org/2006/09/01/kerberos-tgt-validation/ for some ideas on how to resolve TGT validation problems.

One tip not mentioned in that article that may also help: make sure that reverse DNS lookups work for all the servers involved, both Unix and AD.

Hope this helps,
Scott

Thanks Scott for the great article. I was able to get a couple of test servers integrated into AD without any issues. However, I did notice a couple key linux commands broke b/c of it. SU and Sudo do not work anymore and error out on something like “incorrect/invalid password”. Can you confirm this? I know there are su and sudo files in /etc/pam.d but not sure if they require editing. Any help would be greatly appreciated. Thanks!

– Dave

Hello
getent passwd working ok but very slow, I must waiting. ( Ubuntu 6,10)
In Solaris system it’s works much better.

What should I do to make it faster ?

Paul,

If you haven’t already, make sure the UID attribute in Active Directory is indexed. This will improve performance significantly. You might also just check to see if name resolution is working as expected. Delays in DNS will result in delays resolving hostnames, connecting to LDAP servers, etc.

Scott

David,

I don’t recall running into any issues with su or sudo after integrating Linux systems in Active Directory using this methodology; in fact, I know that using su to assume root worked without any issues. You might try editing the /etc/pam.d files for su and sudo to use only local authentication mechanisms (i.e., pam_unix). Just be careful–you can easily lock yourself out of the system if you make a mistake.

Scott

Scott,

Should it work when using su against another AD account and not root? Same thing with sudo. Should I be able to list AD user accounts in the sudoers files? Thanks

– Dave

Nevermind, I was able to get it running now. Thanks!

David,

What was the problem? Did you have to change anything?

Scott

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

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

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

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

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

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

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!!

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

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

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

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

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

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

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

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.