[prev in list] [next in list] [prev in thread] [next in thread] 

List:       pamldap
Subject:    Re: [pamldap] Problems with nss_ldap, pam_ldap
From:       Buchan Milne <bgmilne () obsidian ! co ! za>
Date:       2005-06-22 12:30:17
Message-ID: 42B959D9.2070300 () obsidian ! co ! za
[Download RAW message or body]

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Christopher Smith wrote:
> Hi, all,
> 
> I'm trying to tie together our Windows and Linux machines'
> authentication using nss_ldap back to Active Directory.  Unfortunately
> I've thus far found it to be flaky and unreliable, when it
> works at all.  Since there seem to be a lot of people using this sort of
> thing in production, I'm assuming it's operator error on my part ;) -
> hopefully someone here can help me figure out where I'm going wrong.
> 
> Firstly, I'll describe our environment.  We have a number of Active
> Directory domains like the following:
> 
> nighthawkrad.net
> syd.nighthawkrad.net
> cda.nighthawkrad.net
> 
> The top level nighthawkrad.net contains no "real" users.  It has a
> couple of accounts that are used by services considered to be "global",
> it also contains the account used for LDAP binds.
> 
> The lower level domains - syd, cda, etc contain all the users and groups
> relevant to that location (domains are defined by geographical
> location).  Each location has one DC for the top level domain and two
> DCs for its "local" domain.
> 
> Each location has a number of linux machines.  While nearly all of them
> will never have to host any non-IT-staff logins, there are a few (mail,
> WWW and samba) that I would like to be able to authenticate user
> accounts back to AD.

I will just point out here that if you want to have samba appear to work
as a domain member server (ie have authentication be transparent),
currently the only way to do this is to use winbind (instead of
nss_ldap/pam_ldap).

winbind can also be used for normal user authentication ... but (since
you have more than one domain) it would probably require an LDAP server
(such as OpenLDAP) if you require UIDs to be sync'ed between machines
running winbind (ie if you are going to use NFS between any of the Linux
machines). winbind should also handle inter-domain trusts cleanly (ie,
you would join the server to one of your sub-domains, and it should be
able to authenticate users from a trusted domain). winbind also does its
own caching (and use of nscd with winbind is not recommended).

>  In addition, some IT staff staff log on to all the
> linux machines to perform sysadmin duties.  Fundamentally, I want a
> single username and password for each user, that they can use to logon
> to any of our machines no matter where they or that machine might be, or
> whether that machine is running Linux or Windows.
> 
> I've had limited amounts of success so far.  I've pointed the basedn to
> dc=nighthawkrad,dc=net and set the LDAP servers to be the DCs for the
> top level domain and that seems to work to achieve some sort of
> "recursive" (not sure of the exact LDAP terminology) lookup back to
> users in the syd.nighthawkrad.net domain.

Well, the DCs in the top level domain will probably return referrals for
both of the other domains.

>  Usernames in the
> syd.nighthawkrad.net can login fine, although it takes 30+ seconds to do
> so, typically with the following warning:
> 
> Jun 22 01:41:47 justinstalled sshd[3053]: nss_ldap: reconnecting to LDAP
> server...
> Jun 22 01:41:49 justinstalled sshd[3053]: nss_ldap: reconnected to LDAP
> server after 1 attempt(s)
> 
> Tools like ls, id, etc that have to lookup UIDs, etc off the LDAP server
> are also extremely slow (as to be expected).
> 
> The problems start as soon as I enable nscd, which is necessary for
> anything approaching reasonable performance.  The biggest issue seems to
> be nscd itself, which on my test machine crashes and requires restarting
> on average at _least_ 5 - 10 times every hour.

I haven't seen nscd crash before ... although I haven't had a setup such
as yours (but have used it in a more typical OpenLDAP scenario without
real problems).

You should file a bug with your vendor for this issue (it shouldn't be
related to nss_ldap directly).

>  I have a cron job setup
> to check if nscd is running and restart it if it is not that runs every
> minute, and it's not uncommon at all for it to have crashed and need
> restarting five times in five minutes (yet strangely, sometimes it will
> happily run for over an hour without dying).  Obviously, while nscd is
> running, performance is acceptable - but as soon as it crashes things
> stop working.

nscd isn't the only way to cache user account information. You may be
interested in nss_updatedb, which will load an nss module (such as
nss_ldap), and retreive user/group information using the nss module, and
cache the information to the db files used by nss_db. So, you would have
something like this in /etc/nsswitch.conf:

passwd: files db
group: files db
shadow: files

And, then run 'nss_updatedb ldap' via cron. Unfortunately, AFAIK
RH/Fedora's nss_db (at least on RHEL4 and Fedora Core 3 ... not sure
about Fedora Core 4) uses Berkeley DB < 4.2 ... which means it can't
support an nss_updatedb using transactions ... so you may have to script
around it a bit (to cater for situations when the LDAP servers may not
be available ... since without transaction support, if the LDAP servers
are not available, the existing cache will be removed and no users
cache). However, Fedora still does not have nss_updatedb packages.

I would point out that Mandriva 2005LE has nss_db and nss_updatedb (in
contrib), both compiled against DB4.2 (and thus with transaction support).

> Another curious problem is that while the setup will happily
> authenticate users from the syd.nighthawkrad.net domain, it will not
> authenticate users from the cda.nighthawkrad.net domain, raising this
> error:
> 
> Jun 21 18:42:20 justinstalled sshd[4362]: pam_ldap: error trying to bind
> as user "CN=Jabber Test User,OU=TESTING,DC=cda,DC=nighthawkrad,DC=net"
> (Invalid credentials)

It would be interesting to know which DC it was attempting to bind to
when this failed.

> Jun 21 18:42:22 justinstalled sshd[4362]: Failed password for invalid
> user jabbertest from ::ffff:172.25.253.244 port 4070 ssh2
> 
> A manual ldapsearch binding with the same credentials is successful:
> 
> [root@justinstalled home]# ldapsearch -x -Hldap://pdc01.nighthawkrad.net
> -D "cn=Jabber Test User,ou=TESTING,dc=cda,dc=nighthawkrad,dc=net" -W ""
> Enter LDAP Password:
> # extended LDIF
> #
> # LDAPv3
> # base <> with scope sub
> # filter: (objectclass=*)
> # requesting:
> #
> 
> # nighthawkrad.net
> dn: DC=nighthawkrad,DC=net
> 
> [...]
> 
> # search reference
> ref: ldap://nighthawkrad.net/CN=Configuration,DC=nighthawkrad,DC=net
> 
> # search result
> search: 2
> result: 0 Success
> 
> # numResponses: 301
> # numEntries: 294
> # numReferences: 6
> [root@justinstalled home]#
> 
> Similarly, "getent passwd" only returns usernames from the
> syd.nighthawkrad.net domain, not other domains.  Strangely, "getent
> groups" will return both groups in syd.nighthawkrad.net and
> cda.nighthawkrad.net.  Clearly there are issues with the "recursing",
> but since I really only have a limited understanding of what LDAP is
> doing, I don't even know where to start troubleshooting this.

Running ethereal (maybe only snooping traffic on port 389) on one of the
Linux boxes should allow you to see a bit more of what is happening.

>  The
> configuration files on the Linux machine, however, all only refer to the
> top level nighthawkrad.net.
> 
> My test machine is currently running a freshly installed Fedora Core 4,
> however I have also tested and had similar problems with FC3.  Some
> relevant software versions are:
> 
> nss_ldap-234-4
> openldap-devel-2.2.23-5
> openldap-2.2.23-5
> openldap-clients-2.2.23-5
> 
> My /etc/ldap.conf:
> 
> /etc/ldap.conf
> # @(#)$Id: ldap.conf,v 1.34 2004/09/16 23:32:02 lukeh Exp $
> #
> # This is the configuration file for the LDAP nameservice
> # switch library and the LDAP PAM module.
> #
> # PADL Software
> # http://www.padl.com
> #
> 
> # Your LDAP server. Must be resolvable without using LDAP.
> # Multiple hosts may be specified, each separated by a
> # space. How long nss_ldap takes to failover depends on
> # whether your LDAP client library supports configurable
> # network or connect timeouts (see bind_timelimit).
> host pdc01.nighthawkrad.net
> host pdc02.nighthawkrad.net
> host pdc03.nighthawkrad.net

As Wade Turland pointed out, this should be:

host pdc01.nighthawrad.net pdc02.nighthawrad.net pdc03.nighthawrad.net

These hosts should most likely be resolveable by DNS already (so I don't
think it should be necessary to place them in the hosts file)

> 
> # The distinguished name of the search base.
> base dc=nighthawkrad,dc=net
> 
> # Another way to specify your LDAP server is to provide an
> # uri with the server name. This allows to use
> # Unix Domain Sockets to connect to a local LDAP Server.
> #uri ldap://127.0.0.1/
> #uri ldaps://127.0.0.1/
> #uri ldapi://%2fvar%2frun%2fldapi_sock/
> # Note: %2f encodes the '/' used as directory separator
> 
> # The LDAP version to use (defaults to 3
> # if supported by client library)
> ldap_version 3
> 
> # The distinguished name to bind to the server with.
> # Optional: default is to bind anonymously.
> #binddn cn=Administrator,cn=Users,dc=nighthawkrad,dc=net
> binddn cn=LDAP Search,cn=Users,dc=nighthawkrad,dc=net
> 
> # The credentials to bind with.
> # Optional: default is no credential.
> bindpw ld4ps34rch!
> 
> # The distinguished name to bind to the server with
> # if the effective user ID is root. Password is
> # stored in /etc/ldap.secret (mode 600)
> rootbinddn cn=LDAP Search,cn=Users,dc=nighthawkrad,dc=net
> #rootbinddn cn=Administrator,cn=Users,dc=nighthawkrad,dc=net
> 
> # The port.
> # Optional: default is 389.
> #port 389
> 
> # The search scope.
> scope sub
> #scope one
> #scope base
> 
> # Search timelimit
> #timelimit 30
> 
> # Bind/connect timelimit
> #bind_timelimit 30
> 
> # Reconnect policy: hard (default) will retry connecting to
> # the software with exponential backoff, soft will fail
> # immediately.
> #bind_policy hard
> 
> # Idle timelimit; client will close connections
> # (nss_ldap only) if the server has not been contacted
> # for the number of seconds specified below.
> idle_timelimit 3600
> 
> # Filter to AND with uid=%s
> #pam_filter objectclass=account
> 
> # The user ID attribute (defaults to uid)
> #pam_login_attribute uid
> 
> # Search the root DSE for the password policy (works
> # with Netscape Directory Server)
> #pam_lookup_policy yes
> 
> # Check the 'host' attribute for access control
> # Default is no; if set to yes, and user has no
> # value for the host attribute, and pam_ldap is
> # configured for account management (authorization)
> # then the user will not be allowed to login.
> #pam_check_host_attr yes
> 
> # Check the 'authorizedService' attribute for access
> # control
> # Default is no; if set to yes, and the user has no
> # value for the authorizedService attribute, and
> # pam_ldap is configured for account management
> # (authorization) then the user will not be allowed
> # to login.
> #pam_check_service_attr yes
> 
> # Group to enforce membership of
> #pam_groupdn cn=PAM,ou=Groups,dc=example,dc=com
> 
> # Group member attribute
> #pam_member_attribute uniquemember
> 
> # Specify a minium or maximum UID number allowed
> #pam_min_uid 0
> #pam_max_uid 0
> 
> # Template login attribute, default template user
> # (can be overriden by value of former attribute
> # in user's entry)
> #pam_login_attribute userPrincipalName
> #pam_template_login_attribute uid
> #pam_template_login nobody
> 
> # HEADS UP: the pam_crypt, pam_nds_passwd,
> # and pam_ad_passwd options are no
> # longer supported.
> #
> # If you are using XAD, you can set pam_password
> # to racf, ad, or exop. Make sure that you have
> # SSL enabled.
> 
> # Do not hash the password at all; presume
> # the directory server will do it, if
> # necessary. This is the default.
> #pam_password clear
> 
> # Hash password locally; required for University of
> # Michigan LDAP server, and works with Netscape
> # Directory Server if you're using the UNIX-Crypt
> # hash mechanism and not using the NT Synchronization
> # service.
> #pam_password crypt
> 
> # Remove old password first, then update in
> # cleartext. Necessary for use with Novell
> # Directory Services (NDS)
> #pam_password nds
> 
> # RACF is an alias for the above. For use with
> # IBM RACF
> #pam_password racf
> 
> # Update Active Directory password, by
> # creating Unicode password and updating
> # unicodePwd attribute.
> #pam_password ad
> 
> # Use the OpenLDAP password change
> # extended operation to update the password.
> #pam_password exop
> 
> # Redirect users to a URL or somesuch on password
> # changes.
> #pam_password_prohibit_message Please visit http://internal to change
> your password.
> 
> # configure --enable-authpassword is no longer supported
> # AuthPassword mappings
> #nss_map_attribute userPassword authPassword
> 
> # AIX SecureWay mappings
> #nss_map_objectclass posixAccount aixAccount
> #nss_base_passwd ou=aixaccount,?one
> #nss_map_attribute uid userName
> #nss_map_attribute gidNumber gid
> #nss_map_attribute uidNumber uid
> #nss_map_attribute userPassword passwordChar
> #nss_map_objectclass posixGroup aixAccessGroup
> #nss_base_group ou=aixgroup,?one
> #nss_map_attribute cn groupName
> #nss_map_attribute uniqueMember member
> #pam_login_attribute userName
> #pam_filter objectclass=aixAccount
> #pam_password clear
> 
> # Netscape SDK LDAPS
> #ssl on
> 
> # Netscape SDK SSL options
> #sslpath /etc/ssl/certs/cert7.db
> 
> # OpenLDAP SSL mechanism
> # start_tls mechanism uses the normal LDAP port, LDAPS typically 636
> #ssl start_tls
> #ssl on
> 
> # OpenLDAP SSL options
> # Require and verify server certificate (yes/no)
> # Default is "no"
> #tls_checkpeer yes
> 
> # CA certificates for server certificate verification
> # At least one of these are required if tls_checkpeer is "yes"
> #tls_cacertfile /etc/ssl/ca.cert
> #tls_cacertdir /etc/ssl/certs
> 
> # Seed the PRNG if /dev/urandom is not provided
> #tls_randfile /var/run/egd-pool
> 
> # SSL cipher suite
> # See man ciphers for syntax
> #tls_ciphers TLSv1
> 
> # Client certificate and key
> # Use these, if your server requires client authentication.
> #tls_cert
> #tls_key
> 
> # Disable SASL security layers. This is needed for AD.
> sasl_secprops maxssf=0
> 
> # Override the default Kerberos ticket cache location.
> #krb5_ccname FILE:/etc/.ldapcache
> 
> # SASL mechanism for PAM authentication - use is experimental
> # at present and does not support password policy control
> #pam_sasl_mech DIGEST-MD5
> ssl no
> tls_cacertdir /etc/openldap/cacerts
> pam_password ad
> 
> 
> 
> nss_map_objectclass posixAccount user
> nss_map_objectclass shadowAccount user
> 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_objectclass posixGroup Group
> nss_map_attribute uniqueMember msSFU30PosixMember
> nss_map_attribute cn cn
> pam_login_attribute sAMAccountName
> pam_filter objectclass=user
> pam_member_attribute msSFU30PosixMember
> 
> 
> 
> Anyone who has any ideas as to what's going on and possible fixes,
> please let me know.

I think the big problem here is that you're doing subtree searches
across multiple servers .. which is going to hurt performance.

I am just wondering if a different approach may be better.

One option is winbind (as mentioned above), which you will most likely
need for any servers running samba (if they are to serve files to domain
users).

The second option would be to have an OpenLDAP server dedicated to the
use of the Linux servers, set up with 3 "databases", one for each
sub-domain, each doing caching, and the 3rd one as a "meta" to glue them
together:

database meta
suffix   "dc=nighthawkrad,dc=net"
uri      "ldap://localhost/dc=syd,dc=nighthawkrad,dc=net"
uri      "ldap://localhost/dc=cda,dc=nighthawkrad,dc=net"

You could then use this OpenLDAP server as a source for user information
 (ie nss_ldap), and use pam_krb5 to authenticate users (which would
obviate the need for rewrite rules for binding to authenticate users,
and should also support the inter-domain trusts).

Also, you could use the rewrite engine on the OpenLDAP server to do all
the objectclass/attribute mapping (so configuration on the clients would
be simpler).

Note: I haven't configured such a system ... and this is getting
off-topic for these lists ... the LDAP-interop list may be more relevant
... and the OpenLDAP list would be best for details on configuration of
such an OpenLDAP server.

The 3rd option would be to configure nss_ldap/pam_ldap for each machine
to point at only one sub-domain (which should also allow you to adjust
the nss_base_* configuation entries at a basedn with a "one" search) ...
but I don't think that is going to achieve what you want.

Regards,
Buchan

- --
Buchan Milne                      Senior Support Technician
Obsidian Systems                  http://www.obsidian.co.za
B.Eng          RHCE (803004789010797),LPIC-1 (LPI000074592)

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.0 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

iD8DBQFCuVnZrJK6UGDSBKcRAn8ZAJ0fkEduo4bkGvYI0EuCJXQT+OZvVwCgliLw
J/PENFux+IEY4/JA4JVoEbk=
=2PB0
-----END PGP SIGNATURE-----
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic