home   articles   archive   forum   masthead  
Published at 21.02.06
Author: Marcel Alburg
Translator: Tobias Bayer
Languages: de
Printer printer-version
Support Us!
 

Authenticating to a LDAP server

Reasons for authenticating to an LDAP server.

We assume that you would like to create a web server where a client can log in and then retrieve their e-mails via internet and/or send e-mails etc. (example: www.gmx.de, www.web.de or http://linuxali.dyndns.org:4141 ).

Therefore the client has to become a user on the web server. That means they have to run the web server as root (not recommended) to be able to use the commands useradd and groupadd. Your second option is to put all users into a database, where the system looks at every login and controls individual access if the user exists.

This second opportunity is safer as you have one single location in the network where all users log in (like the NDS from Novell); you can administrate the users at a central point (Single Point of Administration).

Necessary software

OpenLDAP 2.x.x (http://www.openldap.org/software/download/) (In this tutorial OpenLDAP 2.0.12 is used)

Nss_ldap (http://www.padl.com/nss_ldap.html)

Pam_ldap (http://www.padl.com/pam_ldap.html)

Pam-devel (http://www.tuxfinder.com) (only necessary if you did not compile PAM yourself)

Debian users only need the package libpam0g-dev ("apt-get install libpam0g-dev")

OpenLDAP should already be completly configured; if it is not and you have problems look for the tutorial by Thomas Kroll (http://www.linuxnetmag.com/de/issue6/m6ldap 1.html)

Installing the software

First, decompress the packages nss_ldap and pam_ldap by:

  >> tar xvfz nss_ldap....tar.gz
  >> tar xvfz pam_ldap....tar.gz
  
Then compile and install them by:
  >> ./configure
  >> make
  >> make install
  

in each directory.

Installation time will depend on your computer.

Configuring the software

In order to store the following objects, for the LDAP account, you have to adapt the file slapd.conf ( it is in the configuration directory of OpenLDAP).

It should look like this:

Slapd.conf
			
   include		/etc/openldap/schema/core.schema
   include		/etc/openldap/schema/cosine.schema
   include		/etc/openldap/schema/nis.schema
   include		/etc/openldap/schema/inetorgperson.schema
  
   # These are the files which define the objects
   # that are included before starting the server.
   # These entries must be changed.
  
   # The following files should already be present,
   # otherwise the LDAP server would not work properly.
  
   pidfile		/usr/local/var/slapd.pid
   argsfile	        /usr/local/var/slapd.args
  
   # This data is necessary for starting the LDAP server.
  
   database		ldbm
   suffix			"dc=alkronet,dc=de"
  
   # This entry determines the highest object in your LDAP database.
   # This value must be adapted.
  
   rootdn			"cn=Manager,dc=alkronet,dc=de"
  
   # This entry determines a person who has all permissions
   # for the following object in the LDAP database.
   # This value must be adapted.
  
   rootpw		        test
  
   # The root password.
  
   directory	        /usr/local/var/openldap-ldbm
  
   # Directory with the LDAP database.
  
   defaultaccess          write
  
   # Standard permissions for every user.
  
   # Indices to maintain
   index	objectClass eq
  


The file /etc/ldap.conf must also be adapted because the programs nss_ldap and pam_ldap are accessing it (Be careful, do not edit the file: /etc/openldap/ldap.conf). It is also possible that the files are in a different place. If you use the option -sysconfdir= ... at configuration time, the files will reside in the corresponding directory.

Ldap.conf
   host 127.0.0.1
   # host where you can reach the LDAP server
  
   base dc=alkronet,dc=de
  
   # the base of the LDAP server
  
   pam_filter objectclass=posixAccount
  
   # At log in all objects which are contained in the object class
   # posixAccount are searched for the user
  
   pam_login_attribute uid
  
   # also those which have the attribute uid
  
   nss_base_passwd	o=auth_user,dc=alkronet,dc=de?one
   nss_base_shadow	o=auth_user,dc=alkronet,dc=de?one
   nss_base_group	o=auth_group,dc=alkronet,dc=de?one
  
   # names the LDAP place where the account data must be
  
    sslno
  
   # ssl connections  = no
  


Afterwards a file should be created where an organizations container object is put in. This file could look like the following:

User.ldif
   dn: o=auth_user, dc=alkronet, dc=de
   o: auth_user
   objectclass: organization
  
   # these lines create an organizations object
   # which is named "auth_user". Later, new
   # users will be inserted in this object.
  
   dn: o=auth_group, dc=alkronet, dc=de
   o: auth_group
   objectclass: organization
  
  
   dn: cn=user, o=auth_group, dc=alkronet, dc=de
   objectClass: posixGroup
   objectClass: top
   cn: user
   userPassword: {crypt}x
   gidNumber: 10
  
   # here the group "user" with the number 10 is created
  
   dn: uid=tester, o=auth_user, dc=alkronet, dc=de
   uid: tester
   cn: Test Tester
   objectclass: account
   objectclass: posixAccount
   objectclass: top
   objectclass: shadowAccount
   userPassword: test
   shadowLastChange: 11472
   shadowMax: 99999
   shadowWarning: 7
   uidNumber: 1000
   gidNumber: 10
   homeDirectory: /home/tester
   loginShell: /bin/bash
  
   # uid = user- und login name
   # cn = christian name, surname would be sn
   # afterwards the object classes are defined
   # for the quite tricky values with shadow*
   # the manpages of passwd, useradd and
   # shadow should probably be consulted
   # uidNumber = user number or user id
   # gidNumber = group number or id the user belongs to
   # homeDirectory = home directory
   # loginShell = login shell
  


After this file is created it can be added to the LDAP server.

This is done with the command ldapadd.

  >> ldapadd -x -D "cn=manager, dc=alkronet, dc=de" -W -f User.ldif
  

Now the user is included in the LDAP database but the database is not accessed during log in.

So the PAM service must be adapted to the LDAP server.

Preparing the system for authenticating to a LDAP server

First /etc/nsswitch.conf must be edited to tell the system that group-, user- and password information is not only held in files but also on a LDAP server.

This could look like the following:


/etc/nsswitch.conf
   passwd:	ldap files
   group:		ldap files
   shadow:	ldap files
   
   # ldap was added here
   			
   hosts:		files dns
   networks:      files   
   protocols:	db files
   services:	db files
   ethers:	db files
   rpc:		db files
   netgroup:	nis
  


If you compiled the packages nss_ldap and pam_ldap yourself, a file named ldap.conf should exist in the directory /usr/local/etc. If it is not, the option -sysconfdir was used at compile time. You should look in the directory you chose then.

Debian users who have worked with apt-get own the two files pam-ldap.conf and libnss-ldap.conf. These files are the same and you could also create a link (e.g.: ln -snf /etc/pam-ldap.conf /etc/libnss-ldap.conf).

The content of this file determines which LDAP server to authenticate to and which objects contain the user- and password information.

It could look like the following:

Ldap.conf oder ldap-pam.conf
			
   host 127.0.0.1
   # IP des LDAP Servers
   
   base dc=alkronet,dc=de
   # base object of the server
  
   # binddn cn=proxyuser,dc=padl,dc=com
   # bindpw secret
   # rootbinddn cn=manager,dc=padl,dc=com
   # port 389
  
   # if you have to authenticate to the LDAP server to be able
   # to browse data, the user and password have to be
   # named here
  
   # timelimit 30
   # sets how long a user is allowed to browse the LDAP server
  
   # bind_timelimit 30
   # sets how long a user is allowed to be connected
   # to the LDAP server
  
   # idle_timelimit 3600
   # sets the time the connection is automatically cut
   # when the user is idle
  
   pam_filter objectclass=posixAccount
   # search all entries where the object class equals posixAccount
  
   pam_login_attribute uid
   # the username is stored in the attribute uid
  
   nss_base_passwd	o=auth_user, dc=alkronet,dc=de?one
   nss_base_shadow        o=auth_user, dc=alkronet,dc=de?one
   nss_base_group		o=auth_group, dc=alkronet,dc=de?one
  
   # sets the path to the passwords, the shadow entries and the
   # group information
   # ?one  means, that only one entry may be used
   # if there is more than one entry the first found
   # password is used
  			
   sslno
   # SSL connections are not supported
  


Furthermore the configuration files of every service that is running on the system that will authenticate to the LDAP server must be adapted.

The configuration files reside in /etc/pam.d. Some examples are already included with the PAM software and can be found in example.

If you did not compile PAM yourself they should be in /usr/share/doc/pam, /usr/share/doc/packages/pam or /usr/share/doc/libpam.

The file that is accessed during log in is named login and could look like this:


/etc/pam.d/login
   auth		required	/lib/security/pam_securetty.so
   auth		required	/lib/security/pam_nologin.so
   auth		sufficient	/lib/security/pam_ldap.so use_first_pass
   auth		required	/lib/security/pam_unix_auth.so try_first_pass
   account	sufficient	/lib/security/pam_ldap.so
   account	required	/lib/security/pam_unix_acct.so
   password       required	/lib/security/pam_cracklib.so
   password       required	/lib/security/pam_ldap.so
   password       required	/lib/security/pam_pwdb.so use_first_pass
   session	required	/lib/security/pam_unix_session.so
  
   # /lib/security/pam_ldap.so should be available
   # for every section (auth, account, password) now
  
   # use_first_pass means that the first entered password is used
   # and the files (shadow and passwd) are omitted
  


The other files in the directory can also be adapted this way; or you could take the example files from PAM.


Now logging in should be working, but I had to reboot (perhaps some services must be restarted).

PHP script for adding users

add_user.php
   $username = testuser;
   $password = testuser;
   $user_id  = 1005;
   	        	
   $ldap_server = "127.0.0.1";
   $ldap_base   = "dc=alkronet,dc=de";
  
   # Attention: Double user ids could lead to authenticating errors
  
   $entries["uid"]=strtolower($username);
   $entries["cn"]=$username;
   $entries["objectclass"][0]="account";
   $entries["objectclass"][1]="posixAccount";
   $entries["objectclass"][2]="top";
   $entries["objectclass"][3]="shadowAccount";
   $entries["userPassword"]=$password;
   $entries["shadowLastChange"]="11472";
   $entries["shadowMax"]="99999";
   $entries["shadowWarning"]="7";
   $entries["uidNumber"]=$user_id;
   $entries["gidNumber"]="10";
   $entries["homeDirectory"]="/home/".$username;
   $entries["loginShell"]="/bin/false";
   
   $connect  = ldap_connect($ldap_server);
   $bind     = ldap_bind($connect, "cn=manager, ".$ldap_base, "test");
      
   if (!$bind || !$connect) {
      echo "Connection could not be established.";
      exit;
   }
   
   ldap_add($connect, "uid=".strtolower($username).", o=auth_user, ".$ldap_base, $entries);

if (ldap_error($connect) != "Success") { echo "<p>".ldap_error($connect)."</p>"; }





Talkback Area




Enter Own Comment