Tuesday, May 15, 2012

HOWTO : Kerberos KDC with OpenLDAP 2.4 Back-End and SASL GSSAPI Authentication on CentOS 6.2

We continue our OpenLDAP 2.4 series with goal number 8. Recall that our goals are :
  1. Install OpenLDAP 2.4.
  2. Configure Transport Layer Security (TLS).
  3. Manage users and groups in OpenLDAP.
  4. Configure pam_ldap to authenticate users via OpenLDAP.
  5. Use OpenLDAP as sudo's configuration repository.
  6. Use OpenLDAP as automount map repository for autofs.
  7. Use OpenLDAP as NFS netgroup repository again for autofs.
  8. Use OpenLDAP as the Kerberos principal repository.
  9. Setup OpenLDAP backup and recovery.
  10. Setup OpenLDAP replication.
In this document, we will learn how to setup our OpenLDAP 2.4 server as a repository for our Kerberos principals. We will also explore how to configure the client machines. Kerberos is a computer network authentication protocol which works on the basis of "tickets" to allow nodes communicating over a non-secure network to prove their identity to one another in a secure manner. Its designers aimed primarily at a client–server model, and it provides mutual authentication—both the user and the server verify each other's identity. Kerberos protocol messages are protected against eavesdropping and replay attacks. Kerberos builds on symmetric key cryptography and requires a trusted third party, and optionally may use public-key cryptography by utilizing asymmetric key cryptography during certain phases of authentication.

Server Configuration


Enable NTP and make sure your server and clients are synchronized! I will not explain how to setup NTP in this document. There are quite a lot of examples if you need help. Maybe in some other blog post.

Now that we have our OpenLDAP server configured, we can now proceed with the Kerberos 5 server setup. In this blog post, we will create a Kerberos Key Distribution Center server for the realm COMPANY.COM. To start with, as usual, install the appropriate rpm packages. This will also install several dependencies. The words package will create the /usr/share/dict/words directory used by the kadmind(8) service.
sudo yum -y install krb5-pkinit-openssl krb5-server-ldap words

If we followed my blog post series on OpenLDAP, then the Kerberos schema is already installed. But let's take a look, just to be sure.
sudo ldapsearch -LLLY EXTERNAL -H ldapi:/// -b cn=schema,cn=config dn | grep -i kerberos
dn: cn={12}kerberos,cn=schema,cn=config

Sure enough, the schema is right there. This schema has quite a lot of objects. To see them all, run the following query.

sudo ldapsearch -LLLY EXTERNAL -H ldapi:/// -b cn={12}kerberos,cn=schema,cn=config | grep NAME | cut -d' ' -f5 | sort

This command must return some objects. This is important because if the new Kerberos LDAP attributes are not present, kdb5_ldap_util(8) will generate the following error :

kdb5_ldap_util: Kerberos Container create FAILED: No such object while creating realm 'COMPANY.COM'

Ok, so we have the schema and it's objects. But do we have the container for our Kerberos principals?

sudo ldapsearch -LLLY EXTERNAL -H ldapi:/// -b ou=services,dc=company,dc=com dn | grep -i kerberos

No we don't. So we must add the LDAP container for our Kerberos principals. We must also add an LDAP user and group which will be used by Kerberos to talk to the LDAP server. So create a temporary LDIF file.


Use this new file to add the ou=kerberos to our OpenLDAP server. Enter the OpenLDAP manager's password when prompted.

sudo ldapmodify -aH ldapi:/// -f ~/ldap/kerberos.ldif

Assign a password to the new krbadmin user. Make sure to write this password into a secure store (such as KeePass Password Safe or in gpg).

ldappasswd -xWSD "cn=admin,dc=company,dc=com" "cn=krbadmin,ou=users,dc=company,dc=com"

Create the Kerberos configuration file. 


Now create the Kerberos administrator's access control list (ACL) file. Don't confuse this ACL with the OpenLDAP ACLs. They are not the same. We will work on OpenLDAP ACLs in a few minutes.
Edit the Kerberos 5 Authentication Service and Key Distribution Center (AS/KDC) configuration file.


Using another terminal, keep an eye open on the OpenLDAP server log file. This way we can see what the kdb5_ldap_util(8) command generates.

sudo tail -F /var/log/slapd.log

In a different terminal then the one in which we are running the tail(1) command, issue the following to create our Kerberos entries into our OpenLDAP server.

sudo kdb5_ldap_util -D "cn=admin,dc=company,dc=com" create -subtrees "ou=kerberos,ou=services,dc=company,dc=com" -r COMPANY.COM -s

Create the directory where we will store the stash password. This directory is referenced by the ldap_service_password_file variable found in the /etc/krb5.conf file.

sudo mkdir /etc/krb5.d

And extract the cn=krbadmin,ou=users,dc=company,dc=com user's password using kdb5_ldap_util(8).

sudo kdb5_ldap_util -D "cn=admin,dc=company,dc=com" stashsrvpw -f /etc/krb5.d/stash.keyfile cn=krbadmin,ou=users,dc=company,dc=com

You will be prompted for the database Master Password.

It is important that you NOT FORGET this password.

This has created a few entries under our ou=kerberos,ou=services,dc=company,dc=com namespace. To see them, simply run a query.

sudo ldapsearch -LLLY EXTERNAL -H ldapi:/// -b ou=kerberos,ou=services,dc=company,dc=com dn

But besides the cn=admin user, can anybody else see the Kerberos info? That would be unwise. So let's take a look at our current OpenLDAP ACLs.

sudo ldapsearch -LLLY EXTERNAL -H ldapi:/// -b olcDatabase={1}bdb,cn=config olcAccess

dn: olcDatabase={1}bdb,cn=config
olcAccess: {0}to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external
 ,cn=auth" manage  by dn.base="cn=nssproxy,ou=users,dc=company,dc=com" read by
  * auth by * none
olcAccess: {1}to attrs=userPassword,shadowLastChange by self write by dn="cn=a
 dmin,dc=company,dc=com" write by dn="cn=nssproxy,dc=company,dc=com" read by *
  auth by * none
olcAccess: {2}to dn.base="dc=company,dc=com" by dn="cn=admin,dc=company,dc=com
 " manage by dn="cn=nssproxy,dc=company,dc=com" read by * search

What we need to do, is to grant read/write permission to the Kerberos admin user (i.e. cn=krbadmin,ou=users,dc=company,dc=com) on the ou=kerberos subtree. Any other user should not have access to this data. We again proceed to write an LDIF file.


Activate those changes.

sudo ldapmodify -H ldapi:/// -f ~/ldap/kerberos.acl.ldif

Check to see if the new ACL works. Both the cn=admin user and a user with both UID zero and GID zero will be able to see the ou=kerberos subtree. The cn=nssproxy user will not even see the ou=kerberos container while the cn=krbadmin user will be able to read and write to the entire ou=kerberos subtree. We must also check to see if normal users can still use our OpenLDAP server for authentication via pam_ldap and check to see if they can change their LDAP password?

# This returns the entire ou=kerberos,ou=services,dc=company,dc=com subtree.
ldapsearch -xZLLLWD cn=krbadmin,ou=users,dc=company,dc=com -b ou=kerberos,ou=services,dc=company,dc=com dn

# This query should return the « No such object (32) » error.
ldapsearch -xZLLLWD cn=nssproxy,ou=users,dc=company,dc=com -b ou=kerberos,ou=services,dc=company,dc=com dn

# Check to see if the user can change his own LDAP password?
su - test.user
passwd
Changing password for user test.user.
Enter login(LDAP) password: 
New password: 
Retype new password: 
LDAP password information changed for test.user
passwd: all authentication tokens updated successfully.

Very good! :)

When we installed the krb5-server rpm, it configured logrotate(8) to handle two new log files : one for krb5kdc(8) and the other for kadmind(8) as we can see from /etc/logrotate.d/krb5kdc and /etc/logrotate.d/kadmind files. Strangely, the rpm installation does not create those files. So let's create them.

sudo touch /var/log/krb5kdc.log /var/log/kadmind.log

We now need to instruct rsyslogd(8) what to send into those two new files.


Restart rsyslogd(8) for the changes to take effect.

sudo /etc/init.d/rsyslog restart

Make sure the Kerberos daemons start when the machine boots.

sudo chkconfig krb5kdc on
sudo chkconfig kadmin on

And finally, start the Kerberos daemons.

sudo /etc/init.d/krb5kdc start
sudo /etc/init.d/kadmin start

A quick look at the /var/log/krb5kdc.log file should display this line :

May 14 12:53:34 alice krb5kdc[23528]: commencing operation

Using netstat(8), we can see that we now have TCP ports 88 (kerberos), 464 (kpasswd) and 749 (kerberos-adm) in LISTEN mode.

netstat -alnt | egrep ':88|:464|:749'

Congratulations! We now have an operational MIT Kerberos 5 Authentication Service and Key Distribution Center :)

Now what? Well, first, we need to create a principal for the local server. We should also create a test.user principal. Here's how. The lines below in bold are what is actually typed. This is a single session, but we break it down to add some details.

sudo kadmin.local
Authenticating as principal root/admin@COMPANY.COM with password.

Here we create the machine principal for the current server we're currently logged-in.

kadmin.local:  addprinc -randkey host/alice.company.com@COMPANY.COM
WARNING: no policy specified for host/alice.company.com@COMPANY.COM; defaulting to no policy
Principal "host/alice.company.com@COMPANY.COM" created.

Once we have created the host principal, we can add it to the machine's kerberos keytab (i.e. /etc/krb5.keytab)

kadmin.local:  ktadd host/alice.company.com@COMPANY.COM
Entry for principal host/alice.company.com@COMPANY.COM with kvno 2, encryption type aes256-cts-hmac-sha1-96 added to keytab WRFILE:/etc/krb5.keytab.
Entry for principal host/alice.company.com@COMPANY.COM with kvno 2, encryption type aes128-cts-hmac-sha1-96 added to keytab WRFILE:/etc/krb5.keytab.
Entry for principal host/alice.company.com@COMPANY.COM with kvno 2, encryption type des3-cbc-sha1 added to keytab WRFILE:/etc/krb5.keytab.
Entry for principal host/alice.company.com@COMPANY.COM with kvno 2, encryption type arcfour-hmac added to keytab WRFILE:/etc/krb5.keytab.
Entry for principal host/alice.company.com@COMPANY.COM with kvno 2, encryption type des-hmac-sha1 added to keytab WRFILE:/etc/krb5.keytab.
Entry for principal host/alice.company.com@COMPANY.COM with kvno 2, encryption type des-cbc-md5 added to keytab WRFILE:/etc/krb5.keytab.

Next we create a user princpipal for myself and assign a password to this new user.

kadmin.local:  addprinc drobilla@COMPANY.COM
WARNING: no policy specified for drobilla@COMPANY.COM; defaulting to no policy
Enter password for principal "drobilla@COMPANY.COM": 
Re-enter password for principal "drobilla@COMPANY.COM": 
Principal "drobilla@COMPANY.COM" created.

The next user is again for me, but with administrative rights. Remember the /var/kerberos/krb5kdc/kadm5.acl file? That's where it comes into play. The /admin users have administrative rights to the Kerberos realm via that file. That means they can create and destroy users or policies. So make sure we know and trust them!

kadmin.local:  addprinc drobilla/admin@COMPANY.COM
WARNING: no policy specified for drobilla/admin@COMPANY.COM; defaulting to no policy
Enter password for principal "drobilla/admin@COMPANY.COM": 
Re-enter password for principal "drobilla/admin@COMPANY.COM": 
Principal "drobilla/admin@COMPANY.COM" created.

This will list all the current principals in the realm.

kadmin.local:  getprincs
K/M@COMPANY.COM
krbtgt/COMPANY.COM@COMPANY.COM
kadmin/admin@COMPANY.COM
kadmin/changepw@COMPANY.COM
kadmin/history@COMPANY.COM
kadmin/alice.company.com@COMPANY.COM
host/alice.company.com@COMPANY.COM
drobilla@COMPANY.COM
drobilla/admin@COMPANY.COM
  
And this will give more details on the host/alice.company.com@COMPANY.COM principal.

kadmin.local:  getprinc host/alice.company.com@COMPANY.COM
Principal: host/alice.company.com@COMPANY.COM
Expiration date: [never]
Last password change: Mon May 14 12:58:24 EDT 2012
Password expiration date: [none]
Maximum ticket life: 1 day 00:00:00
Maximum renewable life: 0 days 00:00:00
Last modified: Mon May 14 12:58:24 EDT 2012 (root/admin@COMPANY.COM)
Last successful authentication: [never]
Last failed authentication: [never]
Failed password attempts: 0
Number of keys: 6
Key: vno 2, aes256-cts-hmac-sha1-96, Version 5
Key: vno 2, aes128-cts-hmac-sha1-96, Version 5
Key: vno 2, des3-cbc-sha1, Version 5
Key: vno 2, arcfour-hmac, Version 5
Key: vno 2, des-hmac-sha1, Version 5
Key: vno 2, des-cbc-md5, Version 5
MKey: vno 1
Attributes:
Policy: [none]
kadmin.local:  exit

Notice that a new file was created : /etc/krb5.keytab. That's why we ran the kadmin.local binary as root. If we didn't we would've had this error :

kadmin.local
Authenticating as principal drobilla/admin@COMPANY.COM with password.
kadmin.local: Error reading password from stash:  Permission denied while initializing kadmin.local interface

This is because only root has read access to the stash file (i.e. /etc/krb5.d/stash.keyfile). But let's examine what's the content of the /etc/krb5.keytab.

sudo klist -ek /etc/krb5.keytab 

Keytab name: WRFILE:/etc/krb5.keytab
KVNO Principal
---- --------------------------------------------------------------------------
   2 host/alice.company.com@COMPANY.COM (aes256-cts-hmac-sha1-96) 
   2 host/alice.company.com@COMPANY.COM (aes128-cts-hmac-sha1-96) 
   2 host/alice.company.com@COMPANY.COM (des3-cbc-sha1) 
   2 host/alice.company.com@COMPANY.COM (arcfour-hmac) 
   2 host/alice.company.com@COMPANY.COM (des-hmac-sha1) 
   2 host/alice.company.com@COMPANY.COM (des-cbc-md5) 

As we can see, these are all the encryption keys for this particular machine. No wonder the permissions on the file are restricted to root!

We still have one last item on the server side to fix. That's the « bdb_equality_candidates: (krbPrincipalName) not indexed » error we keep having in the /var/log/slapd.log log file. To fix this, we need another LDIF file.


Add those new indexes to the OpenLDAP server.

sudo ldapmodify -aH ldapi:/// -f kerberos.indexes.ldif

Alright, we now have a KDC !

Client Configuration


With a working KDC server, we can now configure client machines and services to use it. Our goals with the clients is to leverage the Kerberos infrastructure to :
  1. Enable sshd(8) Kerberos authentication.
  2. Enable PAM Kerberos authentication.
  3. SASL GSSAPI OpenLDAP authentication.
  4. Use SAS:L GSSAPI Authentication with AutoFS.
So let's start with our first goal.

Enable sshd(8) Kerberos authentication.


Connect to a client machine. IMPORTANT : Kerberos clients require connectivity to the KDC's TCP ports 88 and 749.

ssh bob.company.com

Install required packages.

sudo yum -y install krb5-workstation pam_krb5

Configure the client's /etc/krb5.conf file. The file looks quite a lot like the one found on the server. That means we can send the server's krb5.conf file to the client and use it as a template.

sudo vi /etc/krb5.conf

Create a new machine principal for this host. We run the kadmin(1) command as root so that we can write the resulting keyfile /etc/krb5.keytab. Otherwise, we would get the « No such file or directory while adding key to keytab » error which is not quite explicit enough. We also must use the -p switch to let kadmin know with which principal we want to connect with. If we only try sudo kadmin, then we will get the « Client not found in Kerberos database while initializing kadmin interface » error because we didn't create the root/admin@COMPANY.COM principal. Don't create it either, we want to be able to know who connected with his /admin user. If it's root/admin, there's now way to tell.

sudo kadmin -p drobilla/admin@COMPANY.COM
Authenticating as principal drobilla/admin@COMPANY.COM with password.
Password for drobilla/admin@COMPANY.COM: 

kadmin:  addprinc -randkey host/bob.company.com@COMPANY.COM
kadmin:  ktadd host/bob.company.com@COMPANY.COM
kadmin:  exit

That created the /etc/krb5.keytab. We can now edit /etc/ssh/sshd_config to enable Kerberos authentication. Don't forget to add test.group into the AllowGroups directive. Otherwise we won't be able to test and will have the « User test.user from alice.company.com not allowed because none of user's groups are listed in AllowGroups » in the machine's /var/log/secure log file.

sudo vi /etc/ssh/sshd_config

Restart the daemon.

sudo /etc/init.d/sshd restart

Leave this terminal window open after we've issued this command :

sudo tail -F /var/log/secure

From another terminal window on the server, create a test.user principal.

kadmin -p drobilla/admin@COMPANY.COM
kadmin:  addprinc test.user@COMPANY.COM
WARNING: no policy specified for test.user@COMPANY.COM; defaulting to no policy
Enter password for principal "test.user@COMPANY.COM": 
Re-enter password for principal "test.user@COMPANY.COM": 
Principal "test.user@COMPANY.COM" created.
kadmin:  exit

Assume this user's identity by taking his Kerberos ticket. We first destroy our own tickets with kdestroy(1), then get the test.user's ticket with kinit(1) and finally confirm that we do indeed have the new ticket with klist(1).

kdestroy
kinit -p test.user@COMPANY.COM
Password for test.user@COMPANY.COM: 
klist
Ticket cache: FILE:/tmp/krb5cc_1100
Default principal: test.user@COMPANY.COM

Valid starting     Expires            Service principal
05/14/12 14:12:10  05/15/12 14:12:10  krbtgt/COMPANY.COM@COMPANY.COM
renew until 05/14/12 14:12:10

We can now login with this Kerberos ticket.

ssh test.user@bob.company.com

If we go back to the terminal window on the client in which the tail(1) command was running on the /var/log/secure file, we should have those lines :

May 14 14:09:17 bob sshd[2619]: Authorized to test.user, krb5 principal test.user@COMPANY.COM (krb5_kuserok)
May 14 14:09:17 bob sshd[2619]: Accepted gssapi-with-mic for test.user from 192.168.1.20 port 54891 ssh2
May 14 14:09:17 bob sshd[2619]: pam_unix(sshd:session): session opened for user test.user by (uid=0)

Success! We can now cross our first goal and try the second one.
  1. Enable sshd(8) Kerberos authentication.
  2. Enable PAM Kerberos authentication.
  3. SASL GSSAPI OpenLDAP authentication.
  4. Use SAS:L GSSAPI Authentication with AutoFS.

Enable PAM Kerberos authentication


That shouldn't be too hard since we've already configured pam_ldap in another blog post. Again, we won't be using authconfig(8). To enable PAM kerberos, we need to change the /etc/pam.d/system-auth-ac file.

sudo vi /etc/pam.d/system-auth-ac

And that's it! That was easy :)
  1. Enable sshd(8) Kerberos authentication.
  2. Enable PAM Kerberos authentication.
  3. SASL GSSAPI OpenLDAP authentication.
  4. Use SAS:L GSSAPI Authentication with AutoFS.

SASL GSSAPI OpenLDAP authentication


Server Configuration (part 1 of 2)


To enable SASL GSSAPI authentication, we must configure the OpenLDAP server so that it knows about our Kerberos realm. Then we can configure the clients.

So, from the OpenLDAP server, connect to the KDC and create a new principal. We still use kadmin as root because we want to place the new keytab into /etc/openldap so that our OpenLDAP daemon has a different keytab then the host.

sudo kadmin -p drobilla/admin@COMPANY.COM

kadmin:  addprinc -randkey ldap/alice.company.com@COMPANY.COM
kadmin:  ktadd -k /etc/openldap/krb5.keytab ldap/alice.company.com@COMPANY.COM

Change the permissions on this new file to allow the OpenLDAP server to read it.

sudo chown root:ldap /etc/openldap/krb5.keytab
sudo chmod 640 /etc/openldap/krb5.keytab

Install the required software.

sudo yum -y install cyrus-sasl-gssapi

Check our current configuration to see if we have any SASL directives in there?

sudo ldapsearch -LLLY EXTERNAL -H ldapi:/// -b cn=config -s base | grep -i sasl
olcSaslSecProps: noplain,noanonymous

Ah ha! So we already have olcSaslSecProps: configured. Let's build on that.

vi ~/ldap/sasl.ldif

Well, actually, we wouldn't need to play with olcSaslSecProps: but I left it there because I tried adding the « noactive » keyword. When we do and try to « sudo ldapsearch -LLLY EXTERNAL... » we get the following error :

sudo ldapsearch -LLLY EXTERNAL -H ldapi:/// -b cn=config -s base | grep -i sasl
SASL/EXTERNAL authentication started
ldap_sasl_interactive_bind_s: Authentication method not supported (7)
additional info: SASL(-4): no mechanism available: security flags do not match required

Since that's not exactly what we need at the moment. Maybe later. For now, let's see if our new SASL configuration has been loaded by slapd?

sudo ldapsearch -LLLY EXTERNAL -H ldapi:/// -b cn=config -s base | grep -i sasl
[sudo] password for drobilla: 
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
olcSaslHost: alice.company.com
olcSaslRealm: COMPANY.COM
olcSaslSecProps: noanonymous,noplain 

Good! Now here's a tricky part, we need to add the KRB5_KTNAME parameter to the /etc/sysconfig/ldap file. But this parameter is not part of any OpenLDAP documentation I've ever found?!? A hint about this parameter is found in the /etc/init.d/slapd startup script and that's it! If anyone knows why, please let me know! 


Since we've changed this file, we need to restart slapd(8C) for the changes to take effect. We also stop nslcd(8) which prevents a timeout when slapd(8C) starts.

sudo /etc/init.d/nslcd stop
sudo /etc/init.d/slapd restart
sudo /etc/init.d/nslcd start

Once slapd is back, we can proceed with the client configuration.

Client Configuration (part 1 of 2)


We start by changing the /etc/openldap/ldap.conf file in order to specify that we want to use the SASL GSSAPI authentication mechanism. That's just a single line to change and she's listed in bold.


We then get a ticket from the KDC.

klist
klist: No credentials cache found (ticket cache FILE:/tmp/krb5cc_911)

kinit -p drobilla@COMPANY.COM
Password for drobilla@COMPANY.COM: 

klist
Ticket cache: FILE:/tmp/krb5cc_911
Default principal: drobilla@COMPANY.COM

Valid starting     Expires            Service principal
05/15/12 11:27:17  05/16/12 11:27:17  krbtgt/COMPANY.COM@COMPANY.COM
renew until 05/15/12 11:27:17

We can now see if the SASL GSSAPI authentication works?

ldapwhoami
SASL/GSSAPI authentication started
SASL username: drobilla@COMPANY.COM
SASL SSF: 56
SASL data security layer installed.
dn:uid=drobilla,cn=company.com,cn=gssapi,cn=auth

Success! :) Had we forgot to run kinit before we ran ldapwhoami, we would have had this error :

SASL/GSSAPI authentication started
ldap_sasl_interactive_bind_s: Local error (-2)
additional info: SASL(-1): generic failure: GSSAPI Error: Unspecified GSS failure.  Minor code may provide more information (Credentials cache file '/tmp/krb5cc_1100' not found)

We can now cross our first goal and try the fourth one.
  1. Enable sshd(8) Kerberos authentication.
  2. Enable PAM Kerberos authentication.
  3. SASL GSSAPI OpenLDAP authentication.
  4. Use SAS:L GSSAPI Authentication with AutoFS.
But wait, did you notice that OpenLDAP has changed our Kerberos principal into a OpenLDAP name? We had this principal : 

drobilla@COMPANY.COM

...which was translated by slapd(8C) into this :

dn:uid=drobilla,cn=company.com,cn=gssapi,cn=auth

That means we must now return to the server to install some new ACLs if we want our AutoFS Kerberos principal to be able to read the automount data.

Server Configuration (part 2 of 2)


Back on our OpenLDAP server, we edit another LDIF file to change our ACLs. But before we change anything, it's always good to know what we currently have configured?

ldapsearch -xLLLZWD cn=admin,dc=company,dc=com -b cn=config olcAccess

That query returned three different distinguished names with olcAccess: attributes :

dn: olcDatabase={0}config,cn=config
dn: olcDatabase={1}bdb,cn=config
dn: olcDatabase={2}monitor,cn=config

That means we must now edit the ACL on all three of these distinguished names. Be ready, because the ACL list is getting a little bigger...


Ouf! Did you get all this? Don't be alarmed and read it one by one. You should be fine ;) Still, this looks like a lot of changes, so make a full backup in case things go wrong...

sudo tar zcvf ~/ldap/slapd.d.backup.tar.gz /etc/openldap/slapd.d

Add those news ACLs to our OpenLDAP server.

ldapmodify -xZWD cn=admin,dc=company,dc=com -f ~/ldap/gssapi.ldif

And test to see if we can access what we need? Are users that are not supposed to see things really aren't capable of seeing them? Is our Kerberos kadmin(1) programm still working? Can the cn=nssproxy user do it's job? Let's find out.

Check if the RootDN can still see the configuration? It should return only « dn: cn=config ».

ldapsearch -xLLLZWD cn=admin,dc=company,dc=com -b cn=config -s base dn

Check if a user with both UID and GID set to zero can see the configuration? It should return only « dn: cn=config ».

sudo ldapsearch -LLLY EXTERNAL -H ldapi:/// -b cn=config -s base dn

Check if a /admin principal has access to the configuration? It should return only « dn: cn=config ». But notice how the ldapsearch command line is easier to write :)

kdestroy
kinit -p drobilla/admin@COMPANY.COM
ldapsearch -LLLZb cn=config -s base dn

Check if the cn=nssproxy user can still work? This returns every dn: in the Directory Information Tree except the ones under ou=kerberos.

ldapsearch -xZLLLWD cn=nssproxy,ou=users,dc=company,dc=com -b dc=company,dc=com dn

Can normal users still change their passwords? Well, that changed! If we try the passwd command of a user which is not part of the local /etc/passwd file, instead of trying the OpenLDAP passwd, the passwd(1) command will look the the Kerberos 5 password. That's because we enabled PAM Kerberos. Don't worry, that command will prompt for the Kerberos password.

su - test.user
passwd
Changing password for user test.user.
Kerberos 5 Password: 

Client Configuration (part 2 of 2)


We can now head to the client machine and modify it to use SASL GSSAPI authentication for it's default LDAP queries and the autofs maps. Connect to the client machine with a user that is NOT using an NFS home!

ssh panic@bob.company.com

Check to make sure there is no NFS mounted directories? If there are any, make sure to unmount them before you continue!

df -h 

Change the automount system-wide configuration.


Note that the OPTIONS and LOGGING clauses are set to debug values. This is just to help us find problems if there are any. During normal operations, these should be changed. We'll get to these in a minute. 

Next we need to create a Kerberos principal that will be used by our autofs daemon. We must also add this new principal's keys into the client's keytab.

sudo kadmin -p drobilla/admin@COMPANY.COM
kadmin:  addprinc -randkey autofsclient/bob.company.com@COMPANY.COM
kadmin:  ktadd autofsclient/bob.company.com@COMPANY.COM
kadmin:  exit

We can see that the autofsclient keys are now part of the client's keytab :

sudo klist -ek /etc/krb5.keytab
Keytab name: WRFILE:/etc/krb5.keytab
KVNO Principal
---- --------------------------------------------------------------------------
   2 autofsclient/bob.company.com@COMPANY.COM (aes128-cts-hmac-sha1-96) 
   2 autofsclient/bob.company.com@COMPANY.COM (des-hmac-sha1) 
   2 autofsclient/bob.company.com@COMPANY.COM (arcfour-hmac) 
   2 autofsclient/bob.company.com@COMPANY.COM (des-cbc-md5) 
   4 host/bob.company.com@COMPANY.COM (aes256-cts-hmac-sha1-96) 
   4 host/bob.company.com@COMPANY.COM (aes128-cts-hmac-sha1-96) 
   4 host/bob.company.com@COMPANY.COM (des3-cbc-sha1) 
   4 host/bob.company.com@COMPANY.COM (arcfour-hmac) 
   4 host/bob.company.com@COMPANY.COM (des-hmac-sha1) 
   4 host/bob.company.com@COMPANY.COM (des-cbc-md5) 
   2 autofsclient/bob.company.com@COMPANY.COM (aes256-cts-hmac-sha1-96) 
   2 autofsclient/bob.company.com@COMPANY.COM (des3-cbc-sha1)

We can now change the authentication for autofs to use both SASL GSSAPI and the new principal.


Restart the daemon.

sudo /etc/init.d/autofs stop
sudo /etc/init.d/autofs start

 Check the logs to see if that worked?

sudo less /var/log/messages

May 15 14:46:42 bob automount[5539]: sasl_bind_mech: sasl bind with mechanism GSSAPI succeeded
May 15 14:46:42 bob automount[5539]: do_bind: lookup(ldap): autofs_sasl_bind returned 0
May 15 14:46:42 bob automount[5539]: lookup_one: lookup(ldap): searching for "(&(objectclass=automount)(|(cn=home)(cn=/)(cn=\2A)))" under "ou=auto.nfs,ou=autofs,ou=services,dc=company,dc=com"
May 15 14:46:42 bob automount[5539]: lookup_one: lookup(ldap): getting first entry for cn="home"
May 15 14:46:42 bob automount[5539]: lookup_one: lookup(ldap): examining first entry
May 15 14:46:42 bob automount[5539]: lookup_mount: lookup(ldap): home -> alice.company.com:/export/home
May 15 14:46:42 bob automount[5539]: parse_mount: parse(sun): expanded entry: alice.company.com:/export/home
May 15 14:46:42 bob automount[5539]: parse_mount: parse(sun): gathered options: nodev,nfs4,rsize=8192,wsize=8192
May 15 14:46:42 bob automount[5539]: parse_mount: parse(sun): dequote("alice.company.com:/export/home") -> alice.company.com:/export/home
May 15 14:46:42 bob automount[5539]: parse_mount: parse(sun): core of entry: options=nodev,nfs4,rsize=8192,wsize=8192, loc=alice.company.com:/export/home
May 15 14:46:42 bob automount[5539]: sun_mount: parse(sun): mounting root /nfs, mountpoint home, what alice.company.com:/export/home, fstype nfs, options nodev,nfs4,rsize=8192,wsize=8192
May 15 14:46:42 bob automount[5539]: mount_mount: mount(nfs): root=/nfs name=home what=alice.company.com:/export/home, fstype=nfs, options=nodev,nfs4,rsize=8192,wsize=8192
May 15 14:46:42 bob automount[5539]: mount_mount: mount(nfs): nfs options="nodev,nfs4,rsize=8192,wsize=8192", nosymlink=0, ro=0
May 15 14:46:42 bob automount[5539]: mount_mount: mount(nfs): calling mkdir_path /nfs/home
May 15 14:46:42 bob automount[5539]: mount_mount: mount(nfs): calling mount -t nfs -s -o nodev,nfs4,rsize=8192,wsize=8192 alice.company.com:/export/home /nfs/home

Success! :)

We should now edit the automount system-wide configuration to change it for production mode (i.e. less verbose output). Only those two lines are changed.

vi /etc/sysconfig/autofs

LOGGING="none"
# OPTIONS="-d -v"

And restart the autofs deamon for those changes to take effect.

sudo /etc/init.d/autofs stop
sudo /etc/init.d/autofs start

That's it! We have achieved all of our Kerberos goals!
  1. Enable sshd(8) Kerberos authentication.
  2. Enable PAM Kerberos authentication.
  3. SASL GSSAPI OpenLDAP authentication.
  4. Use SAS:L GSSAPI Authentication with AutoFS.
We also achieved goal number 8 which was :
  1. Install OpenLDAP 2.4.
  2. Configure Transport Layer Security (TLS).
  3. Manage users and groups in OpenLDAP.
  4. Configure pam_ldap to authenticate users via OpenLDAP.
  5. Use OpenLDAP as sudo's configuration repository.
  6. Use OpenLDAP as automount map repository for autofs.
  7. Use OpenLDAP as NFS netgroup repository again for autofs.
  8. Use OpenLDAP as the Kerberos principal repository.
  9. Setup OpenLDAP backup and recovery.
  10. Setup OpenLDAP replication.
Our next blog post will explain how to backup and restore our OpenLDAP server. We will then configure replication. With all the OpenLDAP services which our clients now depend on, we need to add some robustness to our OpenLDAP setup.

HTH,

DA+

References



162 comments:

  1. Update: a quick fix to the following pkinit errors in the /var/log/krb5kdc.log file :

    May 16 12:45:33 alice krb5kdc[1715]: preauth pkinit failed to initialize: No realms configured correctly for pkinit support
    May 16 12:45:33 alice krb5kdc[1715]: No realms configured correctly for pkinit support - Cannot request packet info for udp socket address :: port 88

    Simply remove the krb5-pkinit-openssl package.

    sudo rpm -e krb5-pkinit-openssl

    HTH,

    David

    ReplyDelete
  2. UPDATE : When autofs is configured to use Kerberos in the /etc/autofs_ldap_auth.conf, then we must change the startup procedure in order to have Kerberos start before autofs. Otherwise the NFS home directories are not mounted. To do this, edit /etc/init.d/autofs script to change this line...

    # chkconfig: 345 28 72

    ...with this one...

    # chkconfig: 345 36 72

    Then update the rc directories with these commands.

    sudo chkconfig autofs off
    sudo chkconfig autofs on

    That should fix the problem.

    HTH,

    David

    ReplyDelete
  3. David,

    https://dl.dropbox.com/u/72609528/blog/openldap/var.kerberos.krb5kdc.kadm5.acl throws a 404 error.

    ReplyDelete
  4. @Roberto : it should be fixed now. Thanks!

    ReplyDelete
  5. Great series... an amazing reference. Can you link the sections in each article to their corresponding pages. Would be great to be able to navigate through all this work you've done for the rest of us.

    ReplyDelete
    Replies
    1. Hi Robert,

      Many thanks, I appreciate the kind words. Your idea is a good one, I'll work on it right away!

      Cheers,

      DA+

      Delete
    2. Hello Robert,

      Well, finally it took me a bit more time to implement the links. But I finally found the time this morning.

      Thanks again,

      DA+

      Delete
  6. quick note on this post - when you add the principal for the autofsclient should it not also use the randkey flag ie. addprinc -randkey autofsclient/client.domain.com@DOMAIN.COM

    ReplyDelete
    Replies
    1. You're absolutely right! I'll correct this error right away. Thanks!

      DA+

      Delete
  7. Since I started the kerberos part of this great series (this post) I can no longer login with ldap users... I can see tickets being granted, and the ldap query succeeds but I'm getting an error related to initgroups and the session doesn't get setup for the user.

    "Session setup problem, abort." is the shell feedback.

    In /var/log/secure I see the following:

    Oct 10 17:30:53 turner login: pam_krb5[3945]: authentication succeeds for 'testuser' (testuser@DOMAIN.COM)
    Oct 10 17:30:53 turner login: initgroups: Operation not permitted

    Any ideas? This one is obscure and I'm only asking after an hour of googling.

    ReplyDelete
    Replies
    1. That is quite obscure to me too. Did you enable the nslcd daemon? Not the nscd, but nslcd (the extra L is for LDAP). There is a bug with Ubuntu and nss-ldap, but I'm not sure it applies here (see https://bugs.launchpad.net/ubuntu/+source/at/+bug/509734).

      Are you running with SELinux enabled? Try disabling it to see if that might be the problem? Or do you have a modified login.conf file?

      HTH,

      DA+

      Delete
    2. Distro is CentOS 6.x - the error is definitely obscure... nslcd is running (not nscd), selinux disabled, etc. etc.

      The problem was the other pam.d files referencing sssd instead of ldap, specifically:
      /etc/pam.d/sshd
      /etc/pam.d/fingerprint-auth-ac
      /etc/pam.d/password-auth-ac
      /etc/pam.d/smartcard-auth-ac

      ssh working now - gdm still to be confirmed in the AM

      Delete
    3. Hi Robert,

      So how exactly did you fix the issue? You modified the pam.d files listed in your comment? If so, what changes did you apply to them? If you could describe your fix in detail, I could add it to this blog post. With full credit to you of course :)

      Cheers,

      DA+

      Delete
  8. Hi David,

    Do you have any idea connecting to Microsoft Active Directory? or any idea how to connect it via ldap? via Ubuntu client. I used to try use winbind (for details see https://help.ubuntu.com/community/ActiveDirectoryWinbindHowto) and likewise-open (still based on winbind) and it is working well.

    I'm just curious on connecting to AD, so that able to achieve the single-sign on (SS0) which winbind could not do it. My problems, the what correct DN in authenticating to AD? and getting those accounts/passwords?

    I believe you have an experience on it, as these great articles (blogs) are the living witness of your knowledge. Keep up.

    Thank you,
    Ambot Lang

    ReplyDelete
    Replies
    1. Hello Ambot,

      In order to query an Active Directory (AD) server, you need a DN that has access to the data you're interested in. In general, that usually means a Microsoft Domain Admin. What I usually do is create a user in AD with the Microsoft AD tools. This user is labeled as a service account and not an ordinary user. This is mostly done so that other admins who come into contact with this AD will know what this account is used for. I usually also check the « password never expire » and setup a reminder each year to change it. This is to prevent a failed service during a week-end.

      Then SSL access to the AD should be enabled so that the service account's password and data query results are not sent in clear down the wire.

      Using this user, it's now a question of working out the correct ldapsearch query to fetch the data you need. To help you, check out the default /etc/nslcd.conf file when you install nslcd. It has some default values listed there that are quite good.

      Let me know if this answers your question?

      Regards,

      DA+

      Delete
    2. Hi David,

      I am very confused with nslcd.conf, no luck so far, coz I am aiming to login a user via ldap (using the AD). It quite similar to your post here, but I used to connect through kerberos though.

      There are lot of schema in ldap.conf and no idea what the schema to be used? Does it has relationship with the nslcd.conf? I could not display results using getent.

      What do you mean by service account? or how do i make an ordinary user to it?

      Hope you can enlighten me.

      Delete
    3. Hello Ambot,

      You can achieve user authentication on an Active Directory (AD) server via winbind from the Samba suite (see reference [1] below). It works well, but you have to place the Linux machine into the Kerberos realm of the AD servers (with /etc/krb5.conf as usual). So if you're already using Kerberos in your UNIX environment (like you say you are) then you would need to setup cross-realm trust and authentication for this to work (i.e. keep using your existing UNIX Kerberos realm AND use the AD Kerberos realm at the same time).

      If you don't have an existing UNIX Kerberos realm, then winbind is probably the way to go.

      With that said, one has to know that in AD, user passwords are stored in the « unicodePwd » attribute. But this attribute is never returned by an LDAP search! [2],[3].

      I could go on about how to use AD to authenticate users, but someone called Gred has already wrote two articles on the subject. See [4] and [5] for more information.

      HTH,

      DA+

      [1] http://www.samba.org/samba/docs/man/Samba-HOWTO-Collection/winbind.html

      [2] http://search.cpan.org/~gbarr/perl-ldap/lib/Net/LDAP/FAQ.pod#..._in_MS_Active_Directory_?

      [3] http://msdn.microsoft.com/en-us/library/cc223248(prot.20).aspx

      [4] http://www.techrockdo.com/linux/centos-6-authentication-to-active-directory-part-1

      [5] http://www.techrockdo.com/technology/centos-6-authentication-to-active-directory-part-2

      Delete
    4. I forgot to answer your question :

      > What do you mean by service account?
      > Or how do i make an ordinary user to it?

      You can of course use a normal AD user to bind to the AD. But this user's password will eventually expire. If you have several servers using that user's credentials to bind to the AD machines, then once the password expires, all those server that depend on it will be broken.

      So instead of doing this, what I suggested is to create a service account in AD. This account is just like a normal user, except it has the « Password Never Expires » property. You then configure your servers and workstations that need to bind to AD with that account.

      HTH,

      DA+

      Delete
    5. Ambot, I think you should give the new System Security Services Daemon (SSSD) a Go. Check it out :

      http://fedoraproject.org/wiki/Features/SSSD

      http://www.techrockdo.com/linux/centos-authentication-with-sssd

      HTH,

      DA+

      Delete
  9. Any reason for creating a full Posix account for the krbadmin role? Wouldn't it be better to just use a simpleSecurityObject?

    ReplyDelete
    Replies
    1. Hello Anonymous,

      No specific reason. I just didn't think about it when I built my setup. But yes, I think you're right. The krdadmin role should probably be a simpleSecurityObject.

      Thanks,

      David

      Delete
  10. Cute little girl.

    ReplyDelete
    Replies
    1. Thanks! I should change the picture, because it's actually a little boy, lol :)

      Delete
  11. I thought it was a girl because you used "alice.company.com". But i was wrong !!

    ReplyDelete
    Replies
    1. Ha! ok, then in my next blog post I'll name the machine thomas.company.com :)

      Delete
    2. Actually, if were to have a girl, we had decided that she would be called Alice. That's where the server name came from. So you were not quite far off indeed!

      Delete
  12. oh sweet, so alice should be on the way.LoL

    ReplyDelete
  13. Hi David , I am new to this topic and want you to elaborate on olcSaslSecProps directive. if you dont have it , how do you add it to your database?
    Thanks

    ReplyDelete
    Replies
    1. Hello Anonymous,

      The olcSaslSecProps directive is part of the OpenLDAP Global configuration options which is defined in cn=schema. The SASL directives are installed by adding them to your OpenLDAP server via an LDIF file such as this one https://dl.dropbox.com/u/72609528/blog/openldap/sasl.ldif

      It is installed as part of this article too. And you need the SASL libraries installed on your machines to leverage them of course. That's why we run...

      sudo yum -y install cyrus-sasl-gssapi

      HTH,

      DA+


      Delete
  14. Hi David , I configured my ldap server to use SASL GSSAPI . When I try to authenticate myself from ldap server by generating a tkt from my kerberos server , it works. I chck this by typing "ldapwhoami" on my ldap server. But when i do this on my client , it gives me an error :
    ldap_sasl_interactive_bind_s: Unknown authentication method (-6)
    additional info : SASL(-4): no mechanism available: No worth mechs found
    By the way my client was authenticating the user before using SASL GSSAPI.In addition I havent configured any LDAP ACL's so far.
    THanks

    ReplyDelete
    Replies
    1. Hello Anonymous,

      That should be easy to fix because this exception is thrown when your client doesn't have the required SASL libraries installed. You're using SASL GSSAPI which means you need to have the SASL GSSAPI libraries on your machine. If you're on CentOS or RedHat client, that means installing the cyrus-sasl-gssapi rpm. By default, only the cyrus-sasl-plain is installed. But you don't use this. So, to fix your problem, run this :

      sudo yum -y install cyrus-sasl-gssapi

      And then try to authenticate yourself with your Kerberos principal to the OpenLDAP server and see if this works?

      HTH,

      DA+

      Delete
  15. great it worked like a charm !!

    ReplyDelete
  16. Hi David , I am following your tutorial ,but I have setup my ldap server and kerberos server on two seperate machines. When I reach to a point where I want to populate my kerberos container with all the kerberos principals with this command :
    root@kerberos # kdb_ldap_util -D "cn=admin,dc=xx,dc=xx" create -subtrees "ou=kerberos,ou=services,dc=xx,dc=xx" -r -s
    It throws an error :
    kdb5_ldap_util: Can't contact LDAP server while initializing database
    i can search the ldap server from my kerberos and when i type ldapwhoami , it works fine too, Any ideas what went wrong? Thank you

    ReplyDelete
    Replies
    1. Hello Anonymous,

      I do remember that, in the past when I first started to play with Kerberos, you HAD to have the LDAP server and Kerberos KDC on the same machine. That was because the Kerberos implementation did not talk to the LDAP server via a TCP/IP connection, but via a local socket.

      Now that's not the case anymore as the kdb5_ldap_util(8) man page clearly shows an example where the LDAP server is accessed over the network :

      kdb5_ldap_util -D cn=admin,o=org -H ldaps://ldap-server1.mit.edu create -subtrees o=org -sscope SUB -r ATHENA.MIT.EDU

      Have you tried adding the -H switch to your kdb5_ldap_util command? The -H switch is for the LDAP URI.

      HTH,

      DA+

      Delete
  17. ok , The -H option worked for me and i see some new kerberos principals in my openldap database for my realm.Now the issue is that the krb5kdc and kadmin services refuse to start . the logs are not clear only says"
    root@kerberos# service kadmin start
    kadmind: Can't contact LDAP server while initializing, aborting
    root@kerberos# service krbkdc start
    krb5kdc: cannot initialize realm XXXX.XXX - see log file for details

    Thanks

    ReplyDelete
    Replies
    1. And what do the logs say about this? Check the slapd logs and the kdc logs.

      Ideally, open three shells.

      shell_1$ tail -F /var/log/sldapd.log
      shell_2$ tail -F /var/log/kadmind.log /var/log/krb5kdc.log
      shell_3$ sudo /etc/init.d/kadmin start

      Check the logs, then...

      shell_3$ sudo /etc/init.d/krbkdc start

      Check the logs again.

      Of course that means your rsyslog.conf file sends Kerberos and LDAP logs to these files. Your configuration might be different. Here's what I use :

      # Send slapd(8c) logs to /var/log/slapd.log
      if $programname == 'slapd' then /var/log/slapd.log
      & ~

      # Send krb5kdc(8) logs to /var/log/krb5kdc.log
      if $programname == 'krb5kdc' then /var/log/krb5kdc.log
      & ~

      # Send kadmind(8) logs to /var/log/kadmind.log
      if $programname == 'kadmind' then /var/log/kadmind.log
      & ~

      Make sure you restart rsyslogd if you modify the /etc/rsyslog.conf file.

      Also make sure that both your OpenLDAP and your KDC machines are synchronized to the same NTP servers. This is vital for Kerberos operations.

      HTH,

      DA+

      Delete
  18. I am exactly following your doc, but still my kadmind.log and krb5kdc.log shows the same error as it displays on the screen and my slapd.log has no affect on my starting the kadmind or krb5kdc services.It doesnt even show the ip of my kerberos server. I already synched the time b/w all servers....wooof

    ReplyDelete
    Replies
    1. Well, let's check some other things then :)

      Since your OpenLDAP server is on a different machine than your Kerberos KDC, you might have to tell to both kadmin and krb5kdc that they need to contact the OpenLDAP machine. This can be done by adding the right flags into /etc/sysconfig/kadmin and /etc/sysconfig/krb5kdc respectively.

      If you look at the kadmin(1) man page, the -x flags will tell kadmin where to locate it's LDAP server and how to bind to it (i.e. which credentials to use). See this exerpt from the kadmin(1) man page :

      -x db_args
      Specifies the database specific arguments.

      Options supported for LDAP database are:

      -x host=
      specifies the LDAP server to connect to by a LDAP URI.

      -x binddn=
      specifies the DN of the object used by the administration server to bind to the LDAP
      server. This object should have the read and write rights on the realm container, prin-
      cipal container and the subtree that is referenced by the realm.

      -x bindpwd=
      specifies the password for the above mentioned binddn. It is recommended not to use this
      option. Instead, the password can be stashed using the stashsrvpw command of
      kdb5_ldap_util.


      The same goes for krb5kdc(8) man page :

      The -x db_args option specifies the database specific arguments.

      Options supported for LDAP database are:

      -x nconns=
      specifies the number of connections to be maintained per LDAP server.

      -x host=
      specifies the LDAP server to connect to by a LDAP URI.

      -x binddn=
      specifies the DN of the object used by the KDC server to bind to the LDAP server. This object
      should have the rights to read the realm container, principal container and the subtree that
      is referenced by the realm.

      -x bindpwd=
      specifies the password for the above mentioned binddn. It is recommended not to use this
      option. Instead, the password can be stashed using the stashsrvpw command of kdb5_ldap_util.

      Try configuring krb5kdc and kadmin with these flags and restart them. See if that's better?

      HTH,

      DA+

      Delete
  19. I thought these paramenters were controlled by "krb5.conf" and "kdc.conf" . Anyways I put these flags in my /etc/sysconfig/kadmin file like

    KADMIN_ARGS=
    KRB5REALM=
    -x host= ldap://ldap.example.com
    -x binddn= cn=krbadmin,dc=example,dc=com
    -x bindpwd=

    same for krb5kdc but got this error
    root@kerberos# service kadmin start
    /etc/sysconfig/kadmin: line 3: -x: command not found
    same for line 4 and 5

    ReplyDelete
    Replies
    1. Ah I'm sorry if that doesn't work. It's just that I've never tried to run my KDC seperate from my OpenLDAP server. So I'm working in the dark with you.

      Let's try something else. What happens when you try to launch the krb5kdc service with the -x switch. Like this :

      sudo sh -x /etc/init.d/krb5kdc start

      You will get quite a few lines describing what the script is doing. Our target here is to find out which files it tries to open and which command it's using to perform the KDC startup itself and with which arguments.

      Once we have this, we can try it manually and see if there are other error messages. We can also try to launch it manually with strace(1) to see what it's trying to do and thus isolate where the failure occurs.

      HTH,

      DA+

      Delete
  20. root@kerberos# sudo sh -x /etc/init.d/krb5kdc start
    (truncated output)
    + ./etc/sysconfig/krb5kdc
    ++ KRB5KDC_ARGS=
    ++ KRB5REALM=
    + /bin/bash -c 'ulimit -S -c 0 >/dev/null 2>&1 ; /usr/sbin/krb5kdc -P /var/run/krb5kdc.pid'
    krb5kdc: cannot initialize realm COMPANY.COM -see log file for details
    root@kerberos# tail /var/log/krb5kdc.log
    krb5kdc: Can't contact LDAP server - while initializing database for realm COMPANY.COM
    same for kadmin except the error in the script
    kadmind : Can't contact LDAP server while initializing, aborting

    ReplyDelete
    Replies
    1. Hello again,

      Can you please post the contents of the /etc/krb5.conf file from your KDC machine?

      Thanks,

      David

      Delete
  21. Hi David , sorry I was on vacation. Here is my krb.conf file
    [logging]
    default = FILE:/var/log/krb5libs.log
    kdc = FILE:/var/log/krb5kdc.log
    admin_server = FILE:/var/log/kadmind.log

    [libdefaults]
    default_realm = COMPANY.COM
    dns_lookup_realm = false
    dns_lookup_kdc = false
    ticket_lifetime = 48h
    renew_lifetime = 7d
    forwardable = true
    renewable = true

    [realms]
    COMPANY.COM = {
    kdc = kerb.company.com:88
    admin_server = kerb.company.com:749
    default_domain = company.com
    database_module = openldap_ldapconf
    }

    [domain_realm]
    .company.com = COMPANY.COM
    company.com = COMPANY.COM

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

    [dbmodules]
    openldap_ldapconf = {
    db_library = kldap
    ldap_kerberos_container_dn = ou=kerberos,ou=services,dc=company,dc=com
    ldap_kdc_dn = cn=krbadmin,ou=users,dc=company,dc=com
    # this object needs to have read rights on
    # the realm container, principal container and realm subtrees
    ldap_kadmind_dn = cn=krbadmin,ou=users,dc=company,dc=com
    # this object needs to have read rights on
    # the realm container, principal container and realm subtrees
    ldap_service_password_file = /etc/krb5.d/stash.keyfile
    ldap_server = ldap://ldap.company.com
    #ldap_servers = ldapi:///
    ldap_conns_per_server = 5
    }

    ReplyDelete
    Replies
    1. Hello again,

      I hope you had some good time off :)

      Can you please post your /etc/ldap.conf and /etc/openldap/ldap.conf files? Be sure to edit passwords, if any.

      DA+

      Delete
  22. Hi David, My /etc/openldap/slapd.d/slapd.conf file from my ldap server.

    #
    # See slapd.conf(5) for details on configuration options.
    # This file should NOT be world readable.
    #

    include /etc/openldap/schema/corba.schema
    include /etc/openldap/schema/core.schema
    include /etc/openldap/schema/cosine.schema
    include /etc/openldap/schema/duaconf.schema
    include /etc/openldap/schema/dyngroup.schema
    include /etc/openldap/schema/inetorgperson.schema
    include /etc/openldap/schema/java.schema
    include /etc/openldap/schema/misc.schema
    include /etc/openldap/schema/nis.schema
    include /etc/openldap/schema/ppolicy.schema
    include /etc/openldap/schema/collective.schema
    include /etc/openldap/schema/kerberos.schema
    include /etc/openldap/schema/sudo.schema

    # Allow LDAPv2 client connections. This is NOT the default.
    allow bind_v2

    # Do not enable referrals until AFTER you have a working directory
    # service AND an understanding of referrals.
    #referral ldap://root.openldap.org

    pidfile /var/run/openldap/slapd.pid
    argsfile /var/run/openldap/slapd.args

    # Load dynamic backend modules
    # - modulepath is architecture dependent value (32/64-bit system)
    # - back_sql.la overlay requires openldap-server-sql package
    # - dyngroup.la and dynlist.la cannot be used at the same time

    # modulepath /usr/lib/openldap
    # modulepath /usr/lib64/openldap

    # moduleload accesslog.la
    # moduleload auditlog.la
    # moduleload back_sql.la
    # moduleload chain.la
    # moduleload collect.la
    # moduleload constraint.la
    # moduleload dds.la
    # moduleload deref.la
    # moduleload dyngroup.la
    # moduleload dynlist.la
    # moduleload memberof.la
    # moduleload pbind.la
    # moduleload pcache.la
    # moduleload ppolicy.la
    # moduleload refint.la
    # moduleload retcode.la
    # moduleload rwm.la
    # moduleload seqmod.la
    # moduleload smbk5pwd.la
    # moduleload sssvlv.la
    # moduleload syncprov.la
    # moduleload translucent.la
    # moduleload unique.la
    # moduleload valsort.la
    # The next three lines allow use of TLS for encrypting connections using a
    # dummy test certificate which you can generate by changing to
    # /etc/pki/tls/certs, running "make slapd.pem", and fixing permissions on
    # slapd.pem so that the ldap user or group can read it. Your client software
    # may balk at self-signed certificates, however.
    # TLSCACertificateFile /etc/pki/tls/certs/ca-bundle.crt
    # TLSCertificateFile /etc/pki/tls/certs/slapd.pem
    # TLSCertificateKeyFile /etc/pki/tls/certs/slapd.pem

    # Sample security restrictions
    # Require integrity protection (prevent hijacking)
    # Require 112-bit (3DES or better) encryption for updates
    # Require 63-bit encryption for simple bind
    # security ssf=1 update_ssf=112 simple_bind=64

    # Sample access control policy:
    # Root DSE: allow anyone to read it
    # Subschema (sub)entry DSE: allow anyone to read it
    # Other DSEs:
    # Allow self write access
    # Allow authenticated users read access
    # Allow anonymous users to authenticate
    # Directives needed to implement policy:
    # access to dn.base="" by * read
    # access to dn.base="cn=Subschema" by * read
    # access to *
    # by self write
    # by users read
    # by anonymous auth
    #
    # if no access controls are present, the default policy
    # allows anyone and everyone to read anything but restricts
    # updates to rootdn. (e.g., "access to * by * read")
    #
    # rootdn can always read and write EVERYTHING!

    # enable on-the-fly configuration (cn=config)
    database config
    access to *
    by dn.exact="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
    by * none

    # enable server status monitoring (cn=monitor)
    database monitor
    access to *
    by dn.exact="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" read
    by dn.exact="cn=admin,dc=company,dc=com" read
    by * none
    database bdb
    access to *
    by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
    by dn.base="cn=nss-pam-ldap,ou=users,dc=company,dc=com" read
    by * auth
    by * none

    ReplyDelete
  23. contd

    #logging
    loglevel 256
    #######################################################################
    # database definitions
    #######################################################################
    database config
    rootdn "cn=admin,cn=config"
    rootpw {SSHA}xZ63bP5s34ypAL9eig1CQbq3fbettT+7

    database bdb
    suffix "dc=company,dc=com"
    checkpoint 1024 15
    rootdn "cn=admin,dc=company,dc=com"
    rootpw {SSHA}xxxxxxxxxxxxxxxxxxxxxx

    # Cleartext passwords, especially for the rootdn, should
    # be avoided. See slappasswd(8) and slapd.conf(5) for details.
    # Use of strong authentication encouraged.
    # rootpw secret
    # rootpw {crypt}xxxxxxxxxxxxxxxxxx

    # The database directory MUST exist prior to running slapd AND
    # should only be accessible by the slapd and slap tools.
    # Mode 700 recommended.
    directory /var/lib/ldap/diacs

    # Indices to maintain for this database
    index objectClass eq,pres
    index ou,cn,mail,surname,givenname eq,pres,sub
    index uidNumber,gidNumber,loginShell eq,pres
    index uid,memberUid eq,pres,sub
    index nisMapName,nisMapEntry eq,pres,sub

    # Replicas of this database
    #replogfile /var/lib/ldap/openldap-master-replog
    #replica host=ldap-1.example.com:389 starttls=critical
    # bindmethod=sasl saslmech=GSSAPI
    # authcId=host/ldap-master.example.com@EXAMPLE.COM

    my /etc/openldap/ldap.conf file from my kerberos server:

    #
    # LDAP Defaults
    #

    # See ldap.conf(5) for details
    # This file should be world readable but not world writable.

    #BASE dc=example,dc=com
    #URI ldap://ldap.example.com ldap://ldap-master.example.com:666

    #SIZELIMIT 12
    #TIMELIMIT 15
    #DEREF never
    TLS_CACERTDIR /etc/openldap/cacerts
    URI ldap://ldap.company.com
    #URI ldapi:///
    BASE dc=company,dc=com

    and by the way i dont have any /etc/ldap.conf on my kerberos server or ldap server.
    Thanks

    ReplyDelete
    Replies
    1. Hi,

      Sorry for the very late reply. I just changed jobs and got sick :S

      Anyway, I would try to copy your /etc/openldap/ldap.conf file to the /etc/ldap.conf. Both of these files use most of the same keywords anyway.

      HTH,

      DA+

      Delete
  24. Hi David , Now I have rebuild my openldap server with both ldap and kerberos on the same machine.Now when I start my krb5kdc and kadmind i get this error
    "Error reading password from stash: Bind DN entry missing in stash file..."
    Thanks for your extended support

    ReplyDelete
    Replies
    1. Hello again,

      Your stash file seems broken. Try running this :

      sudo kdb5_ldap_util -D cn=admin,dc=example,dc=org -w a -H ldapi:/// stashsrvpw cn=admin,dc=example,dc=org

      Of course, don't forget to change the command to reflect your own DN.

      For more info, check out this site : http://k5wiki.kerberos.org/wiki/LDAP_on_Kerberos

      HTH,

      DA+

      Delete
  25. Hi David, Nice to see you again. My kerberos admin is krbadmin and my stash file has correct info.The path to my stash file is also correctly mentioned in my krb5.conf file, can it be a permission issue?
    Thanks

    ReplyDelete
    Replies
    1. Hello Anonymous,

      Indeed, it can clearly be a permission issue. You can try to see what goes wrong by running an strace on the startup script. Something like this will show you all the files it tries to open and if it was successful or not :

      sudo strace -ff -eopen /etc/init.d/krbadmin start

      HTH,

      DA+

      Delete
  26. Hi David , My services started successfully now. Actually my krbadmin was in a different ou than my realm container.

    ReplyDelete
    Replies
    1. Aaaaah, good news! Of course that wouldn't work :)

      Delete
  27. Hi David , Sorry to bother you but if you have time can you put some light on what this error means.
    root@ldap$ ldapmodify -xWD cn=admin,dc=company,dc=com -f ~/nssproxy.ldif
    ldapmodify: Invalid format (line 5) entry: "olcDatabase={2}bdb,cn=config
    root@ldap$ cat nssproxy.acl.ldif
    dn: olcDatabase={2}bdb,cn=config
    changetype=modify
    replace: olcAccess
    olcAccess: {0} to *
    dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
    by dn.base="cn=nssproxy,ou=users,dc=company,dc=com" read
    by * auth
    by * none
    Any Ideas why its throwing this error?
    Thanks

    ReplyDelete
    Replies
    1. Hello,

      No bother here :)

      In your comment, you post that the command you run is this one...

      ldapmodify -xWD cn=admin,dc=company,dc=com -f ~/nssproxy.ldif

      ...and you cat the file nssproxy.acl.ldif. But if you look at it, the nssproxy.ldif and nssproxy.acl.ldif files are not the same. Is this just a typo or you really are working with two different files? Because if this is the case, you're looking for trouble ;)

      HTH,

      DA+

      Delete
  28. sorry its a typo infact its the same file, actually at work my company policy doesnt allow internet access, so I have to take results and type it here to you.

    ReplyDelete
    Replies
    1. Ah, I'm sorry for you : no internet access! I'm not sure I can live without internet access :)

      So if it's the right file, was it pulled from this blog post? Because I can't find it here. Anyway, when you do the ldapmodify, what logs are generated? And what is the current ACL setup on your olcDatabase={2}bdb,cn=config?

      You can find out what are your current ACLs with a command similar to this one :

      sudo ldapsearch -LLLY EXTERNAL -H ldapi:/// -b olcDatabase={1}bdb,cn=config olcAccess

      Of course, this example command uses the « olcDatabase={1}bdb,cn=config » instead of your « olcDatabase={2}bdb,cn=config ». So make sure you work on the right database number.

      HTH,

      DA+

      Delete
  29. Moreover my commands
    root@ldap$ ldapsearch -xLLLWD cn=admin,dc=company,dc=com -b olcDatabase={2}bdb,cn=config olcAcess
    No such object (32)
    root@ldap$ ldapsearch -xLLLWD cn=admin, cn=config -b olcDatabase={2}bdb,cn=config olcAccess
    dn: olcDatabase={2}bdb,cn=config

    No olcAccess is found with the last command.

    ReplyDelete
  30. And the reason why I started this discussion is as follows:
    root@ldap$kadmin.local
    Authenticating as principal root/admin@COMPANY.COM with password
    kadmin.local: addprinc testuser
    WARNING : no policy specified for testuser@COMPANY.COM; defaulting to no ploicy
    Enter password for principal "testuser@COMPANY.COM" dirtysecret
    Re-enter password for principal "testuser@COMPANY.COM" dirtysecret
    add_principal: Principal add failed: Insufficient access while creating "testuser@COMPANY.COM".

    ReplyDelete
    Replies
    1. Wow that's strange. First time I've seen this. It looks as if your kerberos admin does not have the rights to write to the OpenLDAP Kerberos container.

      Ok, let's make sure your setup is good. Could you please run this command and send me the output :

      ldapsearch -xLLLWD cn=admin,dc=company,dc=com -b cn=config dn

      HTH,

      DA+

      Delete
  31. Hi David

    root@ldap$ ldapsearch -xLLLWD cn=admin,dc=company,dc=com -b cn=config dn
    No such object (32)
    But if i change the -D to cn=admin,cn=config then it returns all the schema entries plus the databases e.g some database entries are
    ------------------------
    dn: olcDatabase={-1}frontend,cn=config
    dn: olcDatabase={0}config,cn=config
    dn: olcDatabase={1}monitor,cn=config
    dn: olcDatabase={2}bdb,cn=config

    Thank you

    ReplyDelete
    Replies
    1. Hi kifal,

      That would mean your OpenLDAP equivalent of the « root » user is configured as « cn=admin,cn=config » instead of « cn=admin,dc=company,dc=com ». Could that be the case? (I don't have access to my OpenLDAP servers right now, so I can't find find out how to make sure that is the case).

      Now, I'm sorry, but I lost track of the current issue. What was your problem again?

      DA+

      Delete
  32. David here are my databases configured in slapd.conf
    database config
    rootdn "cn=admin,cn=config"
    rootpw {SSHA}xZ63bP5s34ypAL9eig1CQbq3fbettT+7

    database bdb
    suffix "dc=company,dc=com"
    checkpoint 1024 15
    rootdn "cn=admin,dc=company,dc=com"
    rootpw {SSHA}xxxxxxxxxxxxxxxxxxxxxx

    The issue was this:
    And the reason why I started this discussion is as follows:
    root@ldap$kadmin.local
    Authenticating as principal root/admin@COMPANY.COM with password
    kadmin.local: addprinc testuser
    WARNING : no policy specified for testuser@COMPANY.COM; defaulting to no ploicy
    Enter password for principal "testuser@COMPANY.COM" dirtysecret
    Re-enter password for principal "testuser@COMPANY.COM" dirtysecret
    add_principal: Principal add failed: Insufficient access while creating "testuser@COMPANY.COM".

    ReplyDelete
    Replies
    1. Ok, may I ask why you decided to use two different rootdn? Wouldn't it be easier to use the same rootdn for all your databases?

      Anyway, for your problem, what I suggest you do is to open two different shells. In the first shell, you do this command :

      sudo tail -F /path/to/your/sldap.log /path/to/your/kerberos.log

      Then in the second shell, you try the kadmin.local again.

      This will allow you to see the log files as they are generated. Once you have those, then please post them here. This will help us in finding the root cause of your problem.

      HTH,

      DA+

      Delete
  33. I tried to make one rootdn but when I reached to the point where I had to issue the following command , it did not return anything:
    root@ldap$ ldapsearch -xLLLWD cn=admin,dc=company,dc=com -b cn=config dn
    No such object (32)
    Therefore I decided to add another one.Please forgive my limited knowledge but this is the toughest topic I have encountered so far. Actually my slapd.log says:
    slapd[18025]: conn=1018 op=7 ADD dn="krbPrincipalName=testuser@COMPANY.COM,ou=krb5,dc=company,dc=com"
    slapd[18025]: conn=1018 op=7 RESULT tag=105 err=50 text=no write acces to parent

    Moreover i had an exact setting of ou's and subtrees as yours in my kerberos database where my REALM was in a seperate container than my kadmin and nssproxy user but when i tried to start the kerberos services , they gave me an error that they could not find the stash password until i brought them into the same container which in my case is called krb5.

    Thanks

    ReplyDelete
    Replies
    1. Hi kifal,

      No problem, I understand this topic can be a bit daunting. But we'll find the issue :)

      Actually, from the log, we can clearly see that your Kerberos DN does not have write access to the Kerberos container. This line says it :

      slapd[18025]: conn=1018 op=7 RESULT tag=105 err=50 text=no write acces to parent

      See the « no write access to parent »? That means your ACLs are not setup properly. ACLs are probably also the reason why you have the « No such object (32) » error when you do the ldapsearch.

      So what we need to do is to give read/write access to the root/admin@COMPANY.COM user. Actually, we will want to give read/write access to the « ou=krb5,dc=company,dc=com » container to a regular expression like this one : « */admin@COMPANY.COM ».

      This ACL setup is done via the « ~/ldap/kerberos.acl.ldif » file in this blog post. Read it again and make sure you understand it and make sure you change the container from my « ou=kerberos » to your own « ou=krb5 » container.

      HTH,

      DA+

      Delete
  34. ok david million thanks to you , after applying all the ACL's my ldap server has started behaving. At least i can die in peace today. GOD SAVE THE QUEEN.

    ReplyDelete
    Replies
    1. Hi kifal,

      Glad we were able to fix your OpenLDAP setup!

      Cheers,

      DA+

      Delete
  35. Hi Dave, your updating the blog encouraged me that I ask you error messages while working on the last part of autofs mounting from the client machine. Instead of the nice log from your "May 15 14:46:42 bob automount[5539]: sasl_bind_mech: sasl bind with mechanism ..... " I got the autofs error messages as below:

    Apr 16 14:59:13 dyna9 automount[2695]: getuser_func: called with context (nil), id 16385.
    Apr 16 14:59:13 dyna9 automount[2695]: sasl_bind_mech: sasl bind with mechanism GSSAPI succeeded
    Apr 16 14:59:13 dyna9 automount[2695]: do_bind: lookup(ldap): autofs_sasl_bind returned 0
    Apr 16 14:59:13 dyna9 automount[2695]: get_query_dn: lookup(ldap): check search base list
    Apr 16 14:59:13 dyna9 automount[2695]: get_query_dn: lookup(ldap): query failed for search dn ou=autofs,ou=services,dc=rock,dc=lab: No such object
    Apr 16 14:59:13 dyna9 automount[2695]: get_query_dn: lookup(ldap): failed to find query dn under search base dns
    Apr 16 14:59:13 dyna9 automount[2695]: do_bind: lookup(ldap): failed to get query dn
    Apr 16 14:59:13 dyna9 automount[2695]: lookup(ldap): couldn't connect to server ldap://192.168.0.5
    Apr 16 14:59:13 dyna9 automount[2695]: do_reconnect: lookup(ldap): failed to find available server

    ReplyDelete
    Replies
    1. Hello Anonymous,

      My name's David, not Dave. I don't know why, but I'm twitchy about this?!

      Now, what do you see in the ldap logs of the OpenLDAP server at 192.168.0.5 when you start autofs on host dyna9? Suggestion to help debug :

      1. open a shell on the OpenLDAP server 192.168.0.5 and issue the following :

      sudo tail -F /var/log/messages /var/log/ldap.log # or change these paths to your own ldap log.

      2. open TWO shells on the autofs client dyna9 and issue the following in shell number one :

      sudo /etc/init.d/autofs stop # or is it /etc/init.d/automount? I don't remember, sorry :)

      3. issue this command in shell number two :

      sudo tail -F /var/log/messages

      4. Then, back in host dyna9's shell number one, start the autofs daemon again :

      sudo /etc/init.d/autofs start # again, is it /etc/init.d/automount?

      Then watch both shells in which you have the tail commands running. You see the logs generated as you execute the start of the autofs daemon. Check those logs.

      HTH,

      DA+

      Delete
  36. Hi David, Just wanted to make myself clear about certain things in the setup.

    1. When i had only nssproxy.acl on the database. My "getent passwd" command on the ldap client was working, but this command did not work on the ldap server right from the start. i read your blog where you have explained about "getent" but not sure if you meant to type the command on the server or the client? if you meant client then my setup is ok.

    2. After i reached to the step to apply " kerberos.acl" then my "getent" command even stopped working on the client as well. Not sure if this is the normal behaviour. Even when i "su testuser" it says "user does not exist"
    my slapd.log after my getent shadow testuser shows the following entries:
    conn=1011 op=1 SEARCH RESULT tag=101 err=32 nentries=0 text=
    conn=1011 op=2 ABANDON msg=2
    conn=1002 op=5 SRCH base="dc=company,dc=com" scope=2 dref=0 filter="(&(objectClass=posixAccount)(uid=root))"

    3. I have setup my ssh configuration on client but when i try to login from another machine to ldapclient , it cant find the user. Can you put some light on this?

    Thanks

    ReplyDelete
    Replies
    1. Hi kifal,

      So, let's take these one at a time.

      1. The getent command tests your entire system's directory search setup. In other words, it will check the /etc/nsswitch.conf file for the database you need to check (ex. passwd) and then check what are the data sources for this database (ex. file ldap). It will then query these data sources in the order they are listed in the /etc/nsswitch.conf file and try to fetch the data you requested. For example, if you run this...

      getent passwd testuser

      ...and the /etc/nsswitch.conf file has this entry...

      passwd: files ldap

      ...then getent will first check the local /etc/passwd file to see if the testuser is listed there. If not, then it will query the ldap server to see if the testuser is there. If it finds the user, either in /etc/passwd or in ldap, then it will print the info for that entry.

      Of course, if you list ldap in /etc/nsswitch.conf, then you need to have a working ldap setup.

      If the command works on your ldap client, but not on your ldap server, it probably means that the /etc/nsswitch.conf file is not configured on your ldap server to query the ldap server (i.e. itself)

      2. Can you please list all your ACLs for the OpenLDAP server once you apply the kerberos.acl file? Maybe that file changes the ACLs in a way that prevents your OpenLDAP bind user from read access to the passwd and shadow attributes?

      3. Don't forget that if your « getent passwd testuser » and « getent shadow testuser » commands don't work, then your SSH setup will never work as well.

      Don't forget that to query the passwd database, you don't need to be root. But for the shadow database, you need to have super-user access. Try doing a simple « cat /etc/passwd » and you will see that it works. But « cat /etc/shadow » will not work unless you do a « sudo cat /etc/shadow ». It's the same with getent. This will fail...

      getent shadow testuser

      ...but this should work...

      sudo getent shadow testuser

      HTH,

      DA+

      Delete
  37. David , once again thank you for your continous support . here is a list of my acl on the database.
    root@ldap: ldapsearch -xLLLWD cn=admin,cn=config -b olcDatabase={2}bdb,cn=config olcAccess
    dn: olcDatabase={2}bdb,cn=config
    olcAccess: {0}to attrs=userPassword,userPKCS12
    by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
    by dn.exact="cn=nssproxy,ou=users,dc=company,dc=com" read
    by self write
    by anonymous auth
    by * none
    olcAccess: {1}to attrs=shadowLastChange
    by self write
    by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
    by dn.exact="cn=nssproxy,ou=users,dc=company,dc=com" read
    by * none
    olcAccess: {2}to dn.subtree="ou=krb5,dc=company,dc=com"
    by dn.exact="cn=kadmin,ou=krb5,dc=company,dc=com" write
    by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" read
    by * none
    olcAccess: {3}to dn.subtree="dc=company,dc=com"
    by dn.exact="cn=kadmin,ou=krb5,dc=company,dc=com" write
    by dn.exact="cn=nssproxy,ou=users,dc=company,dc=com" read
    by * none

    Thank you

    ReplyDelete
  38. David, Thanks for the prompt reply!!! (sorry, misspelled your first name)
    I followed your instruction and the client site(dyna9)'s message log is same as before. In the server side(192.168.0.5) message log has not propagated any log, but slapd.log has added as below:

    Apr 17 11:54:05 svr slapd[1559]: conn=1188 fd=43 ACCEPT from IP=192.168.0.109:56955 (IP=0.0.0.0:389)
    Apr 17 11:54:05 svr slapd[1559]: conn=1188 op=0 EXT oid=1.3.6.1.4.1.1466.20037
    Apr 17 11:54:05 svr slapd[1559]: conn=1188 op=0 STARTTLS
    Apr 17 11:54:05 svr slapd[1559]: conn=1188 op=0 RESULT oid= err=0 text=
    Apr 17 11:54:05 svr slapd[1559]: conn=1188 fd=43 TLS established tls_ssf=256 ssf=256
    Apr 17 11:54:05 svr slapd[1559]: conn=1012 op=176 SRCH base="ou=kerberos,ou=services,dc=rock,dc=lab" scope=2 deref=0 filter="(&(|(objectClass=krbPrincipalAux)(objectClass=krbPrincipal))(krbPrincipalName=autofsclient/dyna9.rock.lab@ROCK.LAB))"
    Apr 17 11:54:05 svr slapd[1559]: conn=1012 op=176 SRCH attr=krbprincipalname krbcanonicalname objectclass krbprincipalkey krbmaxrenewableage krbmaxticketlife krbticketflags krbprincipalexpiration krbticketpolicyreference krbUpEnabled krbpwdpolicyreference krbpasswordexpiration krbLastFailedAuth krbLoginFailedCount krbLastSuccessfulAuth nsaccountlock krbLastPwdChange krbLastAdminUnlock krbExtraData krbObjectReferences krbAllowedToDelegateTo
    Apr 17 11:54:05 svr slapd[1559]: conn=1012 op=176 SEARCH RESULT tag=101 err=0 nentries=1 text=
    Apr 17 11:54:05 svr slapd[1559]: conn=1012 op=177 SRCH base="ou=kerberos,ou=services,dc=rock,dc=lab" scope=2 deref=0 filter="(&(|(objectClass=krbPrincipalAux)(objectClass=krbPrincipal))(krbPrincipalName=krbtgt/ROCK.LAB@ROCK.LAB))"


    I searched the internet with automount error messages, and found some autofs-5.0.5-32 bug report. I am using
    autofs-5.0.5-74 though.

    ReplyDelete
    Replies
    1. Hello Anonymous,

      What we see from the slapd.log file is that client dyna9 at IP 192.168.0.109 has connected to the server, successfully established a TLS connection and then issued a search for the Kerberos principal « autofsclient/dyna9.rock.lab@ROCK.LAB ». So that's good.

      But on the client side, we don't have logs. What you should do now is to enable verbose logging for autofs on the client machine. To do so, edit the /etc/sysconfig/autofs file en replace the verb « none » with « verbose » for the logging clause. Then do the debug thing again we talked about previously (with multiple shells, tail -F, etc).

      Let me know what the client logs say?

      HTH,

      DA+

      Delete
  39. Thanks David my issue is resolved , there was a typo in acl configuration.
    Bye for now.

    ReplyDelete
    Replies
    1. Ah! Beware of the evil typo of doom! ;)

      Glad everything works now,

      DA+

      Delete
  40. Here is the client's message log:

    Apr 17 13:26:11 dyna9 automount[3182]: autofs stopped
    Apr 17 13:26:12 dyna9 automount[3744]: Starting automounter version 5.0.5-74.el6_4, m
    aster map auto.master
    Apr 17 13:26:12 dyna9 automount[3744]: using kernel protocol version 5.02
    Apr 17 13:26:12 dyna9 automount[3744]: get_query_dn: lookup(ldap): query failed for search dn ou=autofs,ou=services,dc=rock,dc=lab: No such object
    Apr 17 13:26:12 dyna9 automount[3744]: get_query_dn: lookup(ldap): failed to find query dn under search base dns
    Apr 17 13:26:12 dyna9 automount[3744]: do_bind: lookup(ldap): failed to get query dn
    Apr 17 13:26:12 dyna9 automount[3744]: lookup(ldap): couldn't connect to server ldap://svr.rock.lab
    Apr 17 13:26:12 dyna9 automount[3744]: do_reconnect: lookup(ldap): failed to find available server
    Apr 17 13:26:12 dyna9 automount[3744]: get_query_dn: lookup(ldap): query failed for search dn ou=autofs,ou=services,dc=rock,dc=lab: No such object
    Apr 17 13:26:12 dyna9 automount[3744]: get_query_dn: lookup(ldap): failed to find query dn under search base dns
    Apr 17 13:26:12 dyna9 automount[3744]: do_bind: lookup(ldap): failed to get query dn
    Apr 17 13:26:12 dyna9 automount[3744]: lookup(ldap): couldn't connect to server ldap://svr.rock.lab
    [root@tb1 ~]# cat me
    Apr 17 13:26:11 dyna9 automount[3182]: autofs stopped
    Apr 17 13:26:12 dyna9 automount[3744]: Starting automounter version 5.0.5-74.el6_4, master map auto.master
    Apr 17 13:26:12 dyna9 automount[3744]: using kernel protocol version 5.02
    Apr 17 13:26:12 dyna9 automount[3744]: get_query_dn: lookup(ldap): query failed for search dn ou=autofs,ou=services,dc=rock,dc=lab: No such object
    Apr 17 13:26:12 dyna9 automount[3744]: get_query_dn: lookup(ldap): failed to find query dn under search base dns
    Apr 17 13:26:12 dyna9 automount[3744]: do_bind: lookup(ldap): failed to get query dn
    Apr 17 13:26:12 dyna9 automount[3744]: lookup(ldap): couldn't connect to server ldap://svr.rock.lab
    Apr 17 13:26:12 dyna9 automount[3744]: do_reconnect: lookup(ldap): failed to find available server
    Apr 17 13:26:12 dyna9 automount[3744]: get_query_dn: lookup(ldap): query failed for search dn ou=autofs,ou=services,dc=rock,dc=lab: No such object
    Apr 17 13:26:12 dyna9 automount[3744]: get_query_dn: lookup(ldap): failed to find query dn under search base dns
    Apr 17 13:26:12 dyna9 automount[3744]: do_bind: lookup(ldap): failed to get query dn
    Apr 17 13:26:12 dyna9 automount[3744]: lookup(ldap): couldn't connect to server ldap://svr.rock.lab
    Apr 17 13:26:12 dyna9 automount[3744]: do_reconnect: lookup(ldap): failed to find available server
    Apr 17 13:26:12 dyna9 automount[3744]: no mounts in table

    ReplyDelete
    Replies
    1. Ok, do you have a ou=autofs,ou=services,dc=rock,dc=lab object in your OpenLDAP server? If you do, can you try to do an ldapsearch with a) your OpenLDAP admin user and b) the nssproxy user configured in the /etc/openldap/ldap.conf file of the client?

      See if these two queries return the same answer or not? If the query returns the info with the OpenLDAP admin but not with the nssproxy, that means your ACLs are not setup right.

      HTH,

      DA+

      Delete
  41. Yes, I can query ou=autofs,ou=services,dc=rock,dc=lab by both nssproxy, and admin with a same output.

    If I query ou=kerberos,ou=services,dc=rock,dc=lab by nssproxy, it does not have a permission but admin and krbadmin can. Is it the matter?

    ( I forgot I have a google account)
    -Nam

    ReplyDelete
  42. well, I am a little confused. I don't have BINDDN and BINDPW option in /etc/openldap/ldap.conf.

    I also tried with BINDDN and BINDPW in /etc/openldap/ldap.conf inserted, but no luck.

    -Nam

    ReplyDelete
    Replies
    1. Hello Nam,

      Can you please post your /etc/openldap/ldap.conf file? Make sure you remove the password of course.

      And do you have an /etc/ldap.conf file? If you do, then please post it as well.

      Some binaries use /etc/openldap/ldap.conf while others rely on /etc/ldap.conf. I know for sure that sudo uses /etc/ldap.conf. But I haven't done any strace runs to know which files are used by which binaries.

      Anyway, please post the contents of both files.

      Also, make sure you check your slapd.log file on the master OpenLDAP server to see which DN is used for the bind.

      HTH,

      DA+

      Delete
    2. sudo uses /etc/sudo-ldap.conf instead /etc/ldap.conf so, I create a link. here are the ldap.conf

      /etc/openldap/ldap.conf
      BASE dc=rock,dc=lab
      URI ldap://192.168.0.5
      BINDDN cn=nssproxy,ou=users,dc=rock,dc=lab
      BINDPW csusb.edu
      TLS_CACERT /etc/pki/tls/certs/companyCA.crt
      TLS_REQCERT allow
      SASL_MECH GSSAPI
      TIMELIMIT 15
      TIMEOUT 20

      /etc/ldap.conf
      BASE dc=rock,dc=lab
      URI ldap://svr.rock.lab
      BINDDN cn=nssproxy,ou=users,dc=rock,dc=lab
      BINDPW xxx
      TLS_CACERTFILE /etc/pki/tls/certs/companyCA.crt
      TLS_CHECKPEER no
      TIMELIMIT 15
      TIMEOUT 20
      SUDOERS_BASE ou=sudo,ou=services,dc=rock,dc=lab


      Here is the server slapd.log

      Apr 18 10:16:36 svr slapd[1559]: conn=1303 op=1 RESULT tag=97 err=14 text=SASL(0): successful result:
      Apr 18 10:16:36 svr slapd[1559]: conn=1303 op=2 BIND dn="" method=163
      Apr 18 10:16:36 svr slapd[1559]: conn=1303 op=2 RESULT tag=97 err=14 text=SASL(0): successful result:
      Apr 18 10:16:36 svr slapd[1559]: conn=1303 op=3 BIND dn="" method=163
      Apr 18 10:16:36 svr slapd[1559]: conn=1303 op=3 BIND authcid="autofsclient/dyna9.rock.lab@ROCK.LAB" authzid="autofsclient/dyna9.rock.lab@ROCK.LAB"
      Apr 18 10:16:36 svr slapd[1559]: conn=1303 op=3 BIND dn="uid=autofsclient/dyna9.rock.lab,cn=rock.lab,cn=gssapi,cn=auth" mech=GSSAPI sasl_ssf=0 ssf=256
      Apr 18 10:16:36 svr slapd[1559]: conn=1303 op=3 RESULT tag=97 err=0 text=
      Apr 18 10:16:36 svr slapd[1559]: conn=1303 op=4 SRCH base="ou=autofs,ou=services,dc=rock,dc=lab" scope=2 deref=0 filter="(&(objectClass=automountMap)(ou=auto.master))"
      Apr 18 10:16:36 svr slapd[1559]: conn=1303 op=4 SRCH attr=ou
      Apr 18 10:16:36 svr slapd[1559]: conn=1303 op=4 SEARCH RESULT tag=101 err=32 nentries=0 text=
      Apr 18 10:16:36 svr slapd[1559]: conn=1303 op=5 UNBIND
      Apr 18 10:16:36 svr slapd[1559]: conn=1303 fd=38 closed
      Apr 18 10:16:36 svr slapd[1559]: conn=1304 fd=38 ACCEPT from IP=192.168.0.109:60179 (IP=0.0.0.0:389)
      Apr 18 10:16:36 svr slapd[1559]: conn=1304 op=0 EXT oid=1.3.6.1.4.1.1466.20037
      Apr 18 10:16:36 svr slapd[1559]: conn=1304 op=0 STARTTLS
      Apr 18 10:16:36 svr slapd[1559]: conn=1304 op=0 RESULT oid= err=0 text=
      Apr 18 10:16:36 svr slapd[1559]: conn=1304 fd=38 TLS established tls_ssf=256 ssf=256
      Apr 18 10:16:36 svr slapd[1559]: conn=1012 op=438 SRCH base="ou=kerberos,ou=services,dc=rock,dc=lab" scope=2 deref=0 filter="(&(|(objectClass=krbPrincipalAux)(objectClass=krbPrincipal))(krbPrincipalName=autofsclient/dyna9.rock.lab@ROCK.LAB))"
      (&(|(objectClass=krbPrincipalAux)(objectClass=krbPrincipal))(krbPrincipalName=krbtgt/ROCK.LAB@ROCK.LAB))"
      text=
      authcid="autofsclient/dyna9.rock.lab@ROCK.LAB" authzid="autofsclient/dyna9.rock.lab@ROCK.LAB"
      Apr 18 10:16:36 svr slapd[1559]: conn=1304 op=3 BIND dn="uid=autofsclient/dyna9.rock.lab,cn=rock.lab,cn=gssapi,cn=auth" mech=GSSAPI sasl_ssf=0 ssf=256
      Apr 18 10:16:36 svr slapd[1559]: conn=1304 op=3 RESULT tag=97 err=0 text=
      Apr 18 10:16:36 svr slapd[1559]: conn=1304 op=4 SRCH base="ou=autofs,ou=services,dc=rock,dc=lab" scope=2 deref=0 filter="(&(objectClass=automountMap)(ou=auto_master))"
      Apr 18 10:16:36 svr slapd[1559]: conn=1304 op=4 SRCH attr=ou
      Apr 18 10:16:36 svr slapd[1559]: conn=1304 op=4 SEARCH RESULT tag=101 err=32 nentries=0 text=
      Apr 18 10:16:36 svr slapd[1559]: conn=1304 op=5 UNBIND
      Apr 18 10:16:36 svr slapd[1559]: conn=1304 fd=38 closed



      At the bottom part, I see the DN="", Is it normal?
      ( i.e Apr 18 10:16:36 svr slapd[1559]: conn=1304 op=1 BIND dn="" method=163)




      Delete
  43. Hi David , I am glad that we worked out some of the major issues in the setup. So far I understand by kerberizing the ldap client , the user will only be authenticated if it has a valid ticket available, but I am experiencing that even if I dont have any ticket , the user is still authenticated.This behaviuor is slightly different on ldap client and on the system connecting to the client.
    If I have a valid tkt on the ldap client then ssh testuser does not ask for password but ssh testuser from another system still requires password. I was expecting that once you dont have a valid tkt for that user , it wont be authenticated at all ?

    ReplyDelete
    Replies
    1. Hello kifal,

      Once you configure your SSH daemon to allow Kerberos authentication via the Generic Security Service Application Programming Interface (i.e. GSSAPI), then you can connect to the machine with a user that has a valid Kerberos ticket. Unless you want this to be the only authentication mechanism, your SSH daemon will also accept Public/Private DSA and RSA keys as well as normal password authentication. It is thus quite flexible. If you don't want to allow public key or password authentication, you need to remove them from the sshd_config file and restart the sshd service.

      Also, if you have « UsePAM yes » in the sshd_config file, then you need to update your Pluggable Authentication Modules (i.e. PAM) configuration. One way to do this is to use the « sudo authconfig-tui » command. With that, you can decide to enable or disable various authentication modules.

      IMHO, I prefer to configure SSH and PAM to use Kerberos, Public keys and Passwords. Then prevent the root user from connecting via SSH. And setup AllowGroups in the sshd_config file to limit which groups have access to the servers. Then keep only system accounts in the local /etc/passwd and /etc/group files. Use OpenLDAP to keep all the users and groups. And configure /etc/nsswitch.conf to use first the local files and the ldap for group, passwd, shadow and sudoers. I also like to configure a panic user in all my machines which has sudo ALL in the local sudoers file. This user is handy when either OpenLDAP, NFS or Kerberos are broken. Ideally, this user is created during OS installation via KickStart. YMMV of course :)

      HTH,

      DA+

      Delete
  44. Hi David, after many googling, I guess autofs bugs.

    ReplyDelete
  45. Thanks For this blog. This is very helpfull.

    Do you have any blog related to virtualization and clustering on centos 6.3.


    Thanks Again!!!!!!!!!!!!!!!!!!!!!!

    ReplyDelete
    Replies
    1. Hello Anonymous,

      My pleasure, glad I could help!

      I don't have any blogs to refer on virtualisation and clustering I'm afraid. I've used Linux Virtual Server [1] in the past. It works very well and is quite easy to setup.

      And for virtualisation, I worked in environments that used Xen [2], VMware [3] and OpenVZ [4] in the past. They all have some good and bad sides. Usually there is already some form of virtualization when you join a corporation. So I use whatever is already in place. For my home virtualisation needs, I use VirtualBox [5] and VMware.

      HTH,

      DA+

      [1] http://www.linuxvirtualserver.org/
      [2] http://en.wikipedia.org/wiki/Xen
      [3] http://en.wikipedia.org/wiki/VMWare
      [4] http://openvz.org/Main_Page
      [5] https://www.virtualbox.org/

      Delete
  46. Thanks very much! But when I execute the "kadmin.local" I got "kadmin.local: LDAP bind dn value missing while initializing kadmin.local interface", do you know why?

    ReplyDelete
  47. btw assword is f***in' cool :)

    nice blog. Very helpful.

    cheers

    ReplyDelete
  48. Hi,
    I can not set the password for the users. when I try su - test.user and then passwd I get following:

    su - test.user
    -bash-4.1$ passwd
    Changing password for user test.user.
    passwd: Authentication token manipulation error

    In /var/log/secure I only get the messages:
    Oct 4 23:31:04 ldap-02 su: pam_unix(su-l:session): session opened for user test.user by root(uid=0)
    Oct 4 23:31:06 ldap-02 passwd: pam_unix(passwd:chauthtok): user "test.user" does not exist in /etc/passwd

    can you help me please?

    ReplyDelete
    Replies
    1. Hi there,

      You have to make sure that your OS is configured to get the users from the OpenLDAP directory. To do so, try running this command :

      getent passwd test.user

      If that doesn't return anything, you need to edit your /etc/nsswitch.conf file so that the « passwd, group » and « shadow » lines all have « files ldap » listed. Such as this :

      passwd: files ldap

      Then make sure your /etc/ldap.conf and /etc/openldap/ldap.conf files are correctly configured to query you OpenLDAP server(s).

      HTH,

      DA+

      Delete
  49. Hi:
    I didn't add the below lines in slapd.conf at the beginning setup. Is it possible to add it through phpldapadmin and how? Can you share a little bit for password aging policy? The new 2.4.23 config
    database is dfferent from the previous version.
    overlay ppolicy
    ppolicy_default "cn=default,ou=policies,dc=example,dc=com"
    Thank you for this great blogs to help me setup 2.4.23 on CentOS 6.4.

    ReplyDelete
    Replies
    1. Any help? Do I need those two lines in slapd.conf before running slaptest to create slapd.d for password aging policy or not? In the older version than 2.4.23, I used to have to add thses two lines. But in this new version, I am stuck to make the password aging work. Will appreicate it for any help.
      overlay ppolicy
      ppolicy_default "cn=default,ou=policies,dc=example,dc=com"

      Delete
    2. This comment has been removed by the author.

      Delete
    3. Hey,

      > Thank you for this great blogs to help me setup 2.4.23 on CentOS 6.4.

      Glad I could help!

      > Do I need those two lines in slapd.conf before running slaptest to create slapd.d for password aging policy or not?

      This time I can't help you. I haven't been playing much with password aging policies of OpenLDAP. I looked more into the Kerberos ones (which makes me think I should write about it :) So, yeah, good luck with that.

      Say, if you do make it work, may I kindly ask you to share you findings? Thanks in advance!

      > Is it possible to add it through phpldapadmin and how?

      No idea?! I've never used that software (I tend to stay well away from PHP tools, but YMMV). I prefer Apache Directory Studio to manage my LDAP entries. It's a Java app that can thus be used on my home MacBook, on the corporate Linux machines and Windows desktops. But you can't modify slapd.conf(5) via this tool. IMHO it's best to go CLI from there.

      HTH,

      DA+

      Delete
    4. I have a module.ldif like this
      dn: cn=module,cn=config
      objectClass: olcModuleList
      cn: module
      olcModuleLoad: ppolicy
      olcModulePath: /usr/lib64/openldap

      How do I use ldapadd -a -xWD "cn=config" -f module.ldif ? It shows Invalid credentials.
      I need to use ldapadd to add the module.ldif and ppolicy_overlay.ldif, but I can't use ldapadd. Any help? Thank you

      Delete
    5. Hello there,

      Your issue is very easy to fix. It's a simple syntax error. Your command is this...

      ldapadd -a -xWD "cn=config" -f module.ldif

      ...where it should be that...

      ldapadd -a -xWD cn=admin,dc=example,dc=org -b "cn=config" -f module.ldif

      As you can see, I've changed the value right after the -D option. -D asks for the OpenLDAP root user. So make sure you change cn=admin,dc=example,dc=org to your own admin user.

      I've then added a -b flag just before the cn=config. -b points to the base of where the change should be applied. In your case, you want to update your cn=config, so that's why you point to that.

      HTH,

      DA+

      Delete
  50. Ok, I am able to use ldapadd in this way
    ldapadd -Y EXTERNAL -H ldapi:/// -D cn=config -f module.ldif
    ldapadd -Y EXTERNAL -H ldapi:/// -D cn=config -f ppolicy.ldif
    Those two doesn't complain after I add them, but I can't add this
    ldapadd -Y EXTERNAL -H ldapi:/// -D cn=config -f ppolicy-overlay.ldif
    adding new entry "olcOverlay=ppolicy,olcDatabase={2}bdb,cn=config"
    ldap_add: No such object (32)
    matched DN: cn=config

    This is my ppolicy-overlay.ldif
    dn: olcOverlay=ppolicy,olcDatabase={2}bdb,cn=config
    objectClass: olcPPolicyConfig
    olcOverlay: ppolicy
    olcPPolicyDefault: cn=ppolicy,ou=policies,dc=tux,dc=com
    olcPPolicyUseLockout: TRUE
    olcPPolicyHashCleartext: TRUE
    Basically, there is no {2}bdb, but I search the documents and forums, people say it should use {2}bdb. Any help will be appreicated.
    Thanks

    ReplyDelete
  51. Hi:
    These are three files that I added. The pwdAccountLockedTime attribute does show up after the 3 times failure, but the timestamp is 8 hours later. I am not sure why. If anyone is interested in setting password aging, hope these three files can help and work togther to work out. Thank you.
    -b "cn=config" in ldapadd doesn't work, so I use ldapmodify this way
    ldapmodify -a -xWD cn=admin,dc=example,dc=com -f ppolicy.ldif
    cat module.ldif
    dn: cn=module,cn=config
    objectClass: olcModuleList
    cn: module
    olcModuleLoad: ppolicy
    olcModulePath: /usr/lib64/openldap

    cat ppolicy-overlay.ldif
    dn: olcOverlay=ppolicy,olcDatabase={1}bdb,cn=config
    objectClass: olcPPolicyConfig
    olcOverlay: ppolicy
    olcPPolicyDefault: cn=ppolicy,ou=policies,dc=example,dc=com
    olcPPolicyUseLockout: TRUE
    olcPPolicyHashCleartext: TRUE

    cat ppolicy.ldif
    dn: ou=policies,dc=example,dc=com
    objectClass: top
    objectClass: organizationalUnit
    ou: policies
    dn: cn=ppolicy,ou=policies,dc=example,dc=com
    objectClass: top
    objectClass: device
    objectClass: pwdPolicyChecker
    objectClass: pwdPolicy
    cn: ppolicy
    pwdAttribute: userPassword
    pwdInHistory: 3
    pwdMinLength: 8
    pwdMaxFailure: 3
    pwdFailureCountInterval: 0
    pwdCheckQuality: 1
    pwdGraceAuthNLimit: 0
    pwdMaxAge: 7776002
    pwdExpireWarning: 432000
    pwdLockoutDuration: 900
    pwdLockout: TRUE
    pwdMustChange: TRUE
    pwdAllowUserChange: TRUE
    pwdSafeModify: FALSE

    ReplyDelete
    Replies
    1. Hello again,

      Thanks for posting your setup, I'll try to implement it and see if I can add another section to my OpenLDAP blog series. If I do this, I'd like to let everyone know that you did the hard work, but I don't have your name. If you're ok with that, how would you like me to name you? Or to whom should I give credit to? :)

      > Basically, there is no {2}bdb, but I search the documents and forums,
      > people say it should use {2}bdb. Any help will be appreicated.

      For the {2}bdb vs. {1}bdb setup, it all depends on each user's own OpenLDAP servers. Here there are two details: a) the number in curly braces and b) the name of the backend database.

      For a), the number will change depending on how many databases your OpenLDAP server uses. When you write LDIF files, you have to know which number to use. To find that, you can query your cn=config base and look for dn: A command similar to this one should give you that :

      ldapsearch -xLLLZWD cn=admin,dc=example,dc=org -b cn=config dn

      With this info, you will know if you have {2}bdb or {1}bdb for example.

      As for b), the type of backend might change. Some might use hdb or mdb instead of bdb too. See http://www.openldap.org/doc/admin24/backends.html for a bit more info. Note that the hdb backend has superseded the bdb backend, and both will soon be deprecated in favor of the new mdb backend. Also note that each databases in your OpenLDAP server can use different backend solutions. For example, you can have a {0}bdb, {1}hdb and {2}mdb.

      Now, before you write LDIF files, you also need to check this out. To do that, you can use the exact same command as for a) above.

      Once you know both the number and backend, you can then write your LDIF files.

      > The pwdAccountLockedTime attribute does show up after the 3 times failure,
      > but the timestamp is 8 hours later. I am not sure why.

      You mention the pwdAccountLockedTime attribute, but it's not part of the LDIF file you posted and it does not show up in the OpenLDAP documentation?

      Stupid question: are all the machines in your LAN in the same time zone? Are they all synched via NTP?

      HTH,

      DA+

      Delete
  52. Hi David:
    pwdAccountLockedTime is read only attribute. http://www.zytrax.com/books/ldap/ch6/ppolicy.html
    I managed to make everything work now. Automount and ppolicy all work now. But I change to use sss service instead of nslcd and change the ldapbasedn to cn=Manager, dc=test,dc=com. There are many associate files that have to be changed, too.I do get the help from your pam_ldap.conf, autofs_ldap_auth.conf, /etc/pam.d/system*. Without your blog, I probably can't get everything work in Opeldap. This new version in CentOS 6 is much more complex than we used in CentOS 5.5. It was way easier to set up before. Anyhow, if I am allowed by you, I will like to share the files that I edit. I don't want to hijack your blog. Thank you.

    ReplyDelete
    Replies
    1. Hello again Anonymous,

      Glad to see you got managed to get all that you wanted!

      Thanks for the good words and please don't worry about highjacking my blog. I believe knowledge should be shared. So go right ahead and post your solution :)

      Cheers,

      DA+

      Delete
  53. Hi David:
    I will post two sections. Sever files and Client files. By the way, my name is Greg. It is nice to meet you here. I will use my google account to post it and not be anonymous anymore. I strip the domain name and use test.com instead. Hopefully, I don't strip down important piece to make it fail.
    ##SERVER##
    cat /etc/openldap/slapd.conf
    # See slapd.conf(5) for details on configuration options.
    include /etc/openldap/schema/core.schema
    include /etc/openldap/schema/cosine.schema
    include /etc/openldap/schema/inetorgperson.schema
    include /etc/openldap/schema/collective.schema
    include /etc/openldap/schema/corba.schema
    include /etc/openldap/schema/duaconf.schema
    include /etc/openldap/schema/openldap.schema
    include /etc/openldap/schema/dyngroup.schema
    include /etc/openldap/schema/java.schema
    include /etc/openldap/schema/misc.schema
    include /etc/openldap/schema/nis.schema
    include /etc/openldap/schema/ppolicy.schema
    include /etc/openldap/schema/autofs.schema
    include /usr/share/doc/krb5-server-ldap-1.10.3/kerberos.schema
    include /usr/share/doc/sudo-1.8.6p3/schema.OpenLDAP
    allow bind_v2
    pidfile /var/run/openldap/slapd.pid
    argsfile /var/run/openldap/slapd.args
    loglevel 256
    logfile /var/log/slapd.log
    database bdb
    suffix "dc=test,dc=com"
    rootdn "cn=Manager,dc=test,dc=com"
    rootpw secret
    directory /var/lib/ldap
    index objectClass eq,pres
    index ou,cn,mail,surname,givenname eq,pres,sub
    index uidNumber,gidNumber,loginShell eq,pres
    index uid,memberUid eq,pres,sub
    index sudoUser eq
    modulepath /usr/lib64/openldap
    moduleload auditlog.la
    moduleload pcache.la
    imoduleload ppolicy.la
    overlay ppolicy
    ppolicy_default "cn=ppolicy,ou=policies,dc=test,dc=com"
    ppolicy_hash_cleartext
    ppolicy_use_lockout
    moduleload back_sql.la
    access to attrs=userPassword,shadowLastChange
    by self write
    by anonymous auth
    by * none
    access to *
    by self write
    by * read
    database config
    database monitor

    cp -p /usr/share/openldap-servers/DB_CONFIG.example /var/lib/ldap/DB_CONFIG
    echo "" | slapadd -f /etc/openldap/slapd.conf
    slaptest -f /etc/openldap/slapd.conf -F /etc/openldap/slapd.d
    chown -R ldap:ldap /var/lib/ldap
    chown -R ldap:ldap /etc/openldap/slapd.d/
    slapd -f /etc/openldap/slapd.conf -u ldap

    cat base.ldif
    dn: dc=test,dc=com
    dc: test
    objectClass: top
    objectClass: domain

    dn: ou=Hosts,dc=test,dc=com
    ou: Hosts
    objectClass: top
    objectClass: organizationalUnit

    dn: ou=Rpc,dc=test,dc=com
    ou: Rpc
    objectClass: top
    objectClass: organizationalUnit

    dn: ou=Services,dc=test,dc=com
    ou: Services
    objectClass: top
    objectClass: organizationalUnit

    dn: nisMapName=netgroup.byuser,dc=test,dc=com
    nismapname: netgroup.byuser
    objectClass: top
    objectClass: nisMap

    dn: ou=Mounts,dc=test,dc=com
    ou: Mounts
    objectClass: top
    objectClass: organizationalUnit

    dn: ou=Networks,dc=test,dc=com
    ou: Networks
    objectClass: top
    objectClass: organizationalUnit

    dn: ou=People,dc=test,dc=com
    ou: People
    objectClass: top
    objectClass: organizationalUnit

    dn: ou=Group,dc=test,dc=com
    ou: Group
    objectClass: top
    objectClass: organizationalUnit

    dn: ou=Netgroup,dc=test,dc=com
    ou: Netgroup
    objectClass: top
    objectClass: organizationalUnit

    dn: ou=Protocols,dc=test,dc=com
    ou: Protocols
    objectClass: top
    objectClass: organizationalUnit

    dn: ou=Aliases,dc=test,dc=com
    ou: Aliases
    objectClass: top
    objectClass: organizationalUnit

    dn: nisMapName=netgroup.byhost,dc=test,dc=com
    nismapname: netgroup.byhost
    objectClass: top
    objectClass: nisMap

    ldapadd -a -W -x -D "cn=Manager,dc=test,dc=com" -f base.ldif

    ReplyDelete
  54. cat user.ldif
    dn: uid=oracle,ou=People,dc=test,dc=com
    uid: oracle
    cn: Oracle DBA
    objectClass: account
    objectClass: posixAccount
    objectClass: top
    objectClass: shadowAccount
    userPassword: {crypt}
    shadowLastChange: 15588
    shadowMin: 0
    shadowMax: 99999
    shadowWarning: 7
    loginShell: /bin/bash
    uidNumber: 500
    gidNumber: 500
    homeDirectory: /home/oracle
    gecos: Oracle DBA

    ldapadd -a -W -x -D "cn=Manager,dc=test,dc=com" -f user.ldif

    cat group.ldif
    dn: cn=oinstall,ou=Group,dc=test,dc=com
    objectClass: posixGroup
    objectClass: top
    cn: oinstall
    userPassword: {crypt}x
    gidNumber: 500
    memberUid: oracle
    memberUid: oragrid

    ldapadd -a -W -x -D "cn=Manager,dc=test,dc=com" -f group.ldif

    cat nssproxyuser.ldif
    dn: uid=nssproxy,ou=People,dc=test,dc=com
    uid: nssproxy
    cn: nssproxy
    objectClass: account
    objectClass: posixAccount
    objectClass: top
    objectClass: shadowAccount
    userPassword: {SSHA}
    shadowLastChange: 15140
    shadowMin: 0
    shadowMax: 99999
    shadowWarning: 7
    loginShell: /bin/false
    uidNumber: 801
    gidNumber: 801
    homeDirectory: /home/nssproxy
    gecos: Network Service Switch Proxy User

    ldapadd -a -W -x -D "cn=Manager,dc=test,dc=com" -f nssproxyuser.ldif

    cat autofs.ldif
    dn: ou=autofs,ou=Services,dc=test,dc=com
    description: Automount maps
    objectClass: top
    objectClass: organizationalUnit
    ou: AutoFS

    dn: ou=auto.home,ou=autofs,ou=Services,dc=test,dc=com
    objectClass: top
    objectClass: automountMap
    ou: auto.home

    dn: cn=/,ou=auto.home,ou=autofs,ou=Services,dc=test,dc=com
    automountinformation: testfiler:/export/home/&
    cn: /
    objectClass: automount

    dn: ou=auto.master,ou=autofs,ou=Services,dc=test,dc=com
    objectClass: top
    objectClass: automountMap
    ou: auto.master

    dn: cn=/home,ou=auto.master,ou=autofs,ou=Services,dc=test,dc=com
    automountinformation: ldap:testfiler:ou=auto.home
    cn: /home
    objectClass: top
    objectClass: automount

    ldapadd -a -W -x -D "cn=Manager,dc=test,dc=com" -f autofs.ldif

    cat ppolicy.ldif
    dn: ou=policies,dc=test,dc=com
    ou: policies
    objectClass: top
    objectClass: organizationalUnit

    dn: cn=ppolicy,ou=policies,dc=test,dc=com
    objectClass: top
    objectClass: device
    objectClass: pwdPolicy
    cn: ppolicy
    pwdAttribute: userPassword
    pwdInHistory: 3
    pwdMinLength: 8
    pwdMaxFailure: 3
    pwdFailureCountInterval: 0
    pwdCheckQuality: 1
    pwdGraceAuthNLimit: 0
    pwdMaxAge: 7776002
    pwdExpireWarning: 432000
    pwdLockoutDuration: 0
    pwdLockout: TRUE
    pwdMustChange: TRUE
    pwdAllowUserChange: TRUE
    pwdSafeModify: FALSE

    ldapadd -a -W -x -D "cn=Manager,dc=test,dc=com" -f ppolicy.ldif

    ReplyDelete
  55. ##CLIENT##
    cat /etc/openldap/ldap.conf
    scope sub
    pam_password exop
    pam_lookup_polic yes
    URI ldap://centostest/
    BASE dc=test,dc=com

    cat /etc/sssd/sssd.conf
    [domain/default]

    ldap_id_use_start_tls = False
    cache_credentials = False
    ldap_search_base = dc=test,dc=com
    krb5_realm = EXAMPLE.COM
    krb5_server = kerberos.example.com
    id_provider = ldap
    auth_provider = ldap
    chpass_provider = ldap
    ldap_uri = ldap://centostest/
    #ldap_tls_cacertdir = /etc/openldap/cacerts
    ldap_tls_cacertdir = /etc/openldap/cacerts
    [sssd]
    config_file_version = 2
    services = nss, pam, autofs
    domains = default, LDAP

    [nss]
    filter_groups = root
    filter_users = root

    [pam]
    pam_verbosity = 2

    [domain/LDAP]
    access_provider = ldap
    simple_allow_groups = users
    ldap_tls_reqcert = never
    id_provider = ldap
    auth_provider = ldap
    chpass_provider = ldap
    use_fully_qualified_names = false
    ldap_uri = ldap://centostest
    ldap_search_base = dc=linux,dc=verusfinancial,dc=com
    ldap_default_bind_dn = cn=nssproxy,dc=test,dc=com
    ldap_default_authtok_type = password
    ldap_default_authtok = qwer
    #ldap_tls_cacertdir = /etc/openldap/cacerts
    #ldap_tls_cacert = /etc/openldap/cacerts/slapd.pem
    #ldap_id_use_start_tls = true
    ldap_pwd_policy = none
    enumerate = false
    cache_credentials = false

    [autofs]
    autofs_provider = ldap
    ldap_uri = ldap://centostest
    ldap_autofs_search_base = ou=autofs,ou=Services,dc=test,dc=com
    ldap_autofs_map_object_class = automountMap
    ldap_autofs_entry_object_class = automount
    ldap_autofs_map_name = ou
    ldap_autofs_entry_key = cn
    ldap_autofs_entry_value = automountInformation

    cat /etc/sysconfig/authconfig
    IPADOMAINJOINED=no
    USEMKHOMEDIR=no
    USEPAMACCESS=no
    CACHECREDENTIALS=no
    USESSSDAUTH=yes
    USESHADOW=no
    USEWINBIND=no
    PASSWDALGORITHM=sha512
    FORCELEGACY=yes
    USEFPRINTD=no
    FORCESMARTCARD=no
    USEDB=no
    USELDAPAUTH=yes
    USEPASSWDQC=no
    IPAV2NONTP=no
    USELOCAUTHORIZE=no
    USECRACKLIB=yes
    USEIPAV2=no
    USEWINBINDAUTH=no
    USESMARTCARD=no
    USELDAP=yes
    USENIS=no
    USEKERBEROS=no
    USESYSNETAUTH=no
    USESSSD=yes
    USEHESIOD=no

    cat /etc/pam_ldap.conf
    uri ldap://centostest/
    base dc=test,dc=com
    binddn uid=nssproxy,ou=People,dc=test,dc=com
    bindpw qwer1234
    timelimit 15
    bind_timelimit 15
    pam_member_attribute gidNumber
    pam_password md5
    pam_lookup_policy yes
    nss_base_passwd ou=People,dc=test,dc=com
    nss_base_shadow ou=People,dc=test,dc=com
    nss_base_group ou=Group,dc=test,dc=com
    nss_base_netgroup ou=Netgroup,dc=test,dc=com
    ssl no
    tls_cacertdir /etc/openldap/cacerts

    cat /etc/autofs_ldap_auth.conf




    ReplyDelete
  56. cat /etc/pam.d/system-auth-ac
    #%PAM-1.0
    # This file is auto-generated.
    # User changes will be destroyed the next time authconfig is run.
    auth required pam_env.so
    auth sufficient pam_unix.so nullok try_first_pass
    auth requisite pam_succeed_if.so uid >= 500 quiet
    auth sufficient pam_ldap.so use_first_pass
    auth required pam_deny.so

    account required pam_unix.so broken_shadow
    account sufficient pam_succeed_if.so uid < 500 quiet
    account [default=bad success=ok user_unknown=ignore] pam_ldap.so
    account required pam_permit.so

    password requisite pam_cracklib.so try_first_pass retry=3 type=
    password sufficient pam_unix.so sha512 nullok try_first_pass use_authtok
    password sufficient pam_ldap.so use_authtok
    password required pam_deny.so

    session optional pam_keyinit.so revoke
    session required pam_limits.so
    session [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
    session required pam_unix.so
    session optional pam_ldap.so

    cat /etc/pam.d/password-auth-ac
    #%PAM-1.0
    # This file is auto-generated.
    # User changes will be destroyed the next time authconfig is run.
    auth required pam_env.so
    auth sufficient pam_unix.so nullok try_first_pass
    auth requisite pam_succeed_if.so uid >= 500 quiet
    auth sufficient pam_sss.so use_first_pass
    auth required pam_deny.so

    account required pam_unix.so broken_shadow
    account sufficient pam_succeed_if.so uid < 500 quiet
    account [default=bad success=ok user_unknown=ignore] pam_sss.so
    account required pam_permit.so

    password requisite pam_cracklib.so try_first_pass retry=3 type=
    password sufficient pam_unix.so sha512 nullok try_first_pass use_authtok
    password sufficient pam_sss.so use_authtok
    password required pam_deny.so

    session optional pam_keyinit.so revoke
    session required pam_limits.so
    session [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
    session required pam_unix.so
    session optional pam_sss.so

    Then modify the /etc/nsswitch.conf to use sss instad. That's the parts of servers and clients. Thanks.

    ReplyDelete
  57. Hello. Your tutorial is fantastic. I have yet to find another post with as fine a detail as yours. I really appreciate your incremental approach where nearly every step is followed with a means to test the changes, and often what problem/error we might encounter. Further, you take the time to explain why your setup is this way.

    I do have a question though. The https://dl.dropbox.com/u/72609528/blog/openldap/sasl.acl.ldif file contains:

    dn: olcDatabase={0}config,cn=config
    ...
    add: olcAccess
    olcAccess: {1}to attrs=userPassword,shadowLastChange
    ...
    by dn="cn=nssproxy,dc=company,dc=com" read
    ...

    Why here is

    ' by dn="cn=nssproxy,dc=company,dc=com" read'

    instead of

    ' by dn="cn=nssproxy,ou=users,dc=company,dc=com" read'

    or even

    ' by dn.exact="cn=nssproxy,ou=users,dc=company,dc=com" read'

    Any help you can provide is appreciated. Thanks again.

    ReplyDelete
    Replies
    1. Hello Anonymous,

      Thanks for the praise, I'm glad you like it :)

      And to answer your question : you've found what is called an error! Yes, you are correct by saying that the original file was missing the ou=users, so I fixed the file.

      Thank you for letting me know.

      Have fun,

      DA+

      Delete
    2. Hello again,

      Thank you for confirming the entry. My next question is then what should not work with the incorrect DN (i.e., missing the 'ou=users')? Does this mean the 'nssproxy' user would not be able to access the 'userPassword' and 'shadowLastChange' attributes, preventing an LDAP-only user from logging in? Is this problem not seen because at this point in the tutorial we've switched to using Kerberos for authentication?

      OK, so I do have another question (unrelated). Admittedly, I am using Ubuntu 12.04 for the clients and servers, and have adapted your setup (where appropriate) for my network. I have set the 'binddn' and 'bindpw' to use the 'nssproxy' user in the client '/etc/ldap.conf' but seemingly the file must be world-readable. Otherwise, 'getent netgroup XXX' is unable to query the entries. I could not find a solution allowing me to keep this file private so as to hide the 'nssproxy' credentials AND allow the setup to fully work. Also, I could not find a way to specify the proxy credentials elsewhere, i.e., in another file. Have you any suggestion(s)?

      Again, thank you for your help.

      Delete
    3. Hi again,

      > Is this problem not seen because at this point in the tutorial we've
      > switched to using Kerberos for authentication?

      Humm, not sure there. I wrote the DropBox files after I've configured everything. And I don't have access to the OpenLDAP servers I used to write this blog post. But yes, you might just be right about the Kerberos authentication. We would need to test to find out. Disable Kerberos authentication in the PAM modules and try with the wrong DN for nssproxy (i.e. without the ou=users,) and see what happens?

      > I could not find a solution allowing me to keep this file private so as to
      > hide the 'nssproxy' credentials AND allow the setup to fully work.

      You can certainly do that by switching your ldap.conf file to use the GSSAPI SASL authentication instead of the basic authentication. Like this :

      # /etc/openldap/ldap.conf
      #
      # OpenLDAP client configuration.
      # Do NOT confuse this file with /etc/ldap.conf.
      # See ldap.conf(5) for details.
      #
      # David Robillard, April 23rd, 2012.

      BASE dc=example,dc=com
      URI ldap://ldap1.example.com ldap://ldap2.example.com
      SASL_MECH GSSAPI
      TLS_CACERT /etc/pki/tls/certs/rootca.crt
      TLS_REQCERT allow
      NETWORK_TIMEOUT 5
      TIMELIMIT 15
      TIMEOUT 20

      # EOF

      Of course you need Kerberos for this to work.

      HTH,

      David

      Delete
    4. Hi David,

      I really appreciate your help and apologize in advance for what is to be a long posting.

      1) I intend to try disabling Kerberos in PAM, leaving out the 'ou=users', and testing LDAP to verify the net effect. However, I would like to finish setting up everything first.

      2) Regarding the removal of 'binddn' and 'bindpw', I'm getting a bit confused. Given that I'm using Ubuntu, the file names and locations are different. I don't expect you to know these although I would be grateful if you do. I have only been able to get sudo+LDAP to succeed with the binddn/bindpw options set in '/etc/ldap/ldap.conf' and I have only been able to get the netgroup lookups to work with those options set in '/etc/ldap.conf'. The 'SASL_MECH GSSAPI' option seems to make no difference for me, with or without the bind information in either file.

      3) When attempting to load the https://dl.dropboxusercontent.com/u/72609528/blog/openldap/sasl.acl.ldif via 'ldapmodify', I ran into a couple a problems. Once loaded, I attempted to confirm loading of the contents but found two entries with what I thought was garbage:

      dn: olcDatabase={0}config,cn=config
      olcAccess:: ezB9dG8gKiAgYnkgZG4uYmFzZT0iZ2lkTnVtYmVyPTArdWlkTnVtYmVyPTAsY249cGlcmNyZWQsY249ZXh0ZXJuYWwsY249YXV0aCIgbWFuYWdlIGJ5IGRuLmJhc2U9ImNuPWFkbWluLGRjPXNwb25nZW1pbmRlZCxkYz1vcmciIG1hbmFnZSAgYnkgZG4ucmVnZXg9InVpZD0uKi9hZG1pbixjbj1zcG9uZ2VtaW5kZWQub3JnLGNuPWdzc2FwaSxjbj1hdXRoIiBtYW5hZ2UgYnkgKiBub25lIA==
      olcAccess: {1}to attrs=userPassword,shadowLastChange by dn.regex="uid=.*/admi
      n


      dn: olcDatabase={1}hdb,cn=config

      olcAccess:: ezR9dG8gZG4uc3VidHJlZT0ib3U9YXV0b2ZzLG91PXNlcnZpY2VzLGRjPXNwb25nZW1pbmRlZCxkYz1vcmciIGJ5IGRuLnJlZ2V4PSJ1aWQ9YXV0b2ZzY2xpZW50Ly4qLGNuPXNwb25nZW1pbmRlZC5vcmcsY249Z3NzYXBpLGNuPWF1dGgiIHJlYWQg

      After some searching, the double colon suggests an illegal character or something of the like in those entries of the LDIF file. It seems both of the corresponding entries in the LDIF have a trailing space character at the end of the line:

      dn: olcDatabase={0}config,cn=config

      olcAccess: {0}to *
      ..
      by * none
      (the above line has a trailing space)

      and

      dn: olcDatabase={1}hdb,cn=config

      olcAccess: {4}to dn.subtree="ou=autofs,ou=services,dc=company,dc=com"
      by dn.regex="uid=autofsclient/.*,cn=company.com,cn=gssapi,cn=auth" read
      (the above line has a trailing space)

      Regarding the latter, this appears to be the only entry that does not specify 'by * none' leading me to ask if it is accidentally missing (and therefore leading to the error). After removing the spaces from each line, I was then able to load the contents.

      (Spliting the post due to size limitation)

      Delete
    5. (Continued from previous post)

      Unfortunately I am stuck here as autofs is no longer mounting my shares. On my test machine, I restart the autofs service and observe the log results:

      // test machine
      Mar 1 04:23:25 test3 automount[1612]: Starting automounter version 5.0.6, master map /etc/auto.master
      Mar 1 04:23:25 test3 automount[1612]: using kernel protocol version 5.02
      Mar 1 04:23:25 test3 automount[1612]: lookup_nss_read_master: reading master file /etc/auto.master
      Mar 1 04:23:25 test3 automount[1612]: parse_init: parse(sun): init gathered global options: (null)
      Mar 1 04:23:25 test3 automount[1612]: lookup_read_master: lookup(file): read entry +auto.master
      Mar 1 04:23:25 test3 automount[1612]: lookup_nss_read_master: reading master ldap auto.master
      Mar 1 04:23:25 test3 automount[1612]: parse_init: parse(sun): init gathered global options: (null)
      Mar 1 04:23:25 test3 automount[1612]: lookup(file): failed to read included master map auto.master
      Mar 1 04:23:25 test3 automount[1612]: no mounts in table

      // Kerberos server
      Mar 1 04:23:25 kerberos1 krb5kdc[1232]: AS_REQ (4 etypes {18 17 16 23}) 192.168.0.208: NEEDED_PREAUTH: autofsclient/test3.company.com@COMPANY.COM for krbtgt/COMPANY.COM@COMPANY.COM, Additional pre-authentication required
      Mar 1 04:23:25 kerberos1 krb5kdc[1232]: AS_REQ (4 etypes {18 17 16 23}) 192.168.0.208: ISSUE: authtime 1393665805, etypes {rep=18 tkt=18 ses=18}, autofsclient/test3.company.com@COMPANY.COM for krbtgt/COMPANY.COM@COMPANY.COM
      Mar 1 04:23:25 kerberos1 krb5kdc[1232]: TGS_REQ (4 etypes {18 17 16 23}) 192.168.0.208: ISSUE: authtime 1393665805, etypes {rep=18 tkt=18 ses=18}, autofsclient/test3.company.com@COMPANY.COM for ldap/ldap1.company.com@COMPANY.COM

      // LDAP server
      Mar 1 04:23:25 ldap1 slapd[1009]: conn=1183 op=1 BIND dn="" method=163
      Mar 1 04:23:26 ldap1 slapd[1009]: conn=1183 op=1 RESULT tag=97 err=14 text=SASL(0): successful result:
      Mar 1 04:23:26 ldap1 slapd[1009]: conn=1183 op=2 BIND dn="" method=163
      Mar 1 04:23:26 ldap1 slapd[1009]: conn=1183 op=2 RESULT tag=97 err=14 text=SASL(0): successful result:
      Mar 1 04:23:26 ldap1 slapd[1009]: conn=1183 op=3 BIND dn="" method=163
      Mar 1 04:23:26 ldap1 slapd[1009]: conn=1183 op=3 BIND authcid="autofsclient/test3.company.com@COMPANY.COM" authzid="autofsclient/test3.company.com@COMPANY.COM"
      Mar 1 04:23:26 ldap1 slapd[1009]: conn=1183 op=3 BIND dn="uid=autofsclient/test3.company.com,cn=company.com,cn=gssapi,cn=auth" mech=GSSAPI sasl_ssf=0 ssf=128
      Mar 1 04:23:26 ldap1 slapd[1009]: conn=1183 op=3 RESULT tag=97 err=0 text=
      Mar 1 04:23:26 ldap1 slapd[1009]: conn=1183 op=4 SRCH base="ou=autofs,ou=services,dc=company,dc=com" scope=2 deref=0 filter="(&(objectClass=automountMap)(ou=auto.master))"
      Mar 1 04:23:26 ldap1 slapd[1009]: conn=1183 op=4 SRCH attr=ou
      Mar 1 04:23:26 ldap1 slapd[1009]: conn=1183 op=4 SEARCH RESULT tag=101 err=32 nentries=0 text=
      Mar 1 04:23:26 ldap1 slapd[1009]: conn=1183 op=5 UNBIND
      Mar 1 04:23:26 ldap1 slapd[1009]: conn=1183 fd=22 closed

      Everything looks good until the search for 'base=”ou=autofs,...” which returns err=32 (No Such Object). Manually searching the LDAP database I see:

      ldapsearch -xLLLZWD cn=admin,dc=company,dc=com -b ou=autofs,ou=services,dc=company,dc=com "(&(objectClass=automountMap)(ou=auto.master))"
      Enter LDAP Password:
      dn: ou=auto.master,ou=autofs,ou=services,dc=company,dc=com
      ou: auto.master
      objectClass: top
      objectClass: automountMap

      ldapsearch -xLLLZWD cn=admin,dc=company,dc=com -b olcDatabase={1}hdb,cn=config olcAccess

      dn: olcDatabase={1}hdb,cn=config

      olcAccess: {4}to dn.subtree="ou=autofs,ou=services,dc=company,dc=com" by
      dn.regex="uid=autofsclient/.*,cn=company.com,cn=gssapi,cn=auth" read

      which looks like it should work.

      I am sure you have better things to do but if something happens to pop out and you feel like responding it would be a great help.

      Thank you. Jerry.

      Delete
    6. Hello Jerry,

      I have no problem with long postings :)

      For your questions number 2) about using Ubuntu, it's quite easy to find which files a particular command needs. Simply install strace [1] on your machine if it's not already there. Then run your command with the -eopen switch. For example :

      sudo strace -eopen ldapwhoami

      You will get a trace of each files the ldapwhoami tries to open. With that, you should be able to find out which ldap.conf file is being used by which commands.

      As for questions number 3) you found out how the garbage came. I must say I'm happy because I've never dug deep enough to figure that one out! I'll go ahead and update the DropBox files right now. Thanks!

      And for the automounter, what did you list in your nsswitch.conf(5) file? Mine reads this :

      automount: ldap

      Which asks the automounter to query only the LDAP server for the mounts. And not the local /etc/auto.master Your setup seems to check the local auto.master file.

      On the OpenLDAP server, you do seem to have a ou=autofs, but there doesn't seem to be anything in it? Can you please send me the output of this query :

      ldapsearch -xLLLZWD cn=admin,dc=example,dc=com -b ou=autofs,ou=services,dc=example,dc=com

      Mine returns this ;

      Enter LDAP Password:
      dn: ou=autofs,ou=services,dc=example,dc=com
      ou: AutoFS
      objectClass: top
      objectClass: organizationalUnit
      description: Automount maps

      dn: ou=auto.master,ou=autofs,ou=services,dc=example,dc=com
      ou: auto.master
      objectClass: top
      objectClass: automountMap

      dn: cn=/nfs,ou=auto.master,ou=autofs,ou=services,dc=example,dc=com
      cn: /nfs
      objectClass: top
      objectClass: automount
      automountInformation: ldap:ou=auto.nfs,ou=autofs,ou=services,dc=example,dc=c
      om rsize=8192,wsize=8192

      dn: ou=auto.nfs,ou=autofs,ou=services,dc=example,dc=com
      ou: auto.nfs
      objectClass: top
      objectClass: automountMap

      dn: cn=home,ou=auto.nfs,ou=autofs,ou=services,dc=example,dc=com
      objectClass: top
      objectClass: automount
      cn: home
      automountInformation: nfs1.example.com:/export/home

      dn: cn=install,ou=auto.nfs,ou=autofs,ou=services,dc=example,dc=com
      objectClass: top
      objectClass: automount
      cn: install
      automountInformation: nfs1.example.com:/export/install

      What do you have?

      Cheers,

      DA+

      Delete
    7. Hi David,

      Glad the long posts are not a bother. Your pointing me at 'strace' was great and the file switch did show me what files are used by 'sudo' or 'ldapwhoami' (for example).

      The automount entries in the database are:

      admin@ldap1:~$ ldapsearch -xLLLZWD cn=admin,dc=company,dc=com -b ou=autofs,ou=services,dc=company,dc=com
      Enter LDAP Password:
      dn: ou=autofs,ou=services,dc=company,dc=com
      ou: AutoFS
      objectClass: top
      objectClass: organizationalUnit
      description: Automount maps

      dn: ou=auto.master,ou=autofs,ou=services,dc=company,dc=com
      ou: auto.master
      objectClass: top
      objectClass: automountMap

      dn: cn=/home,ou=auto.master,ou=autofs,ou=services,dc=company,dc=com
      cn: /home
      objectClass: top
      objectClass: automount
      automountInformation: ldap:ou=auto.home,ou=autofs,ou=services,dc=company,
      dc=com --timeout=5 --ghost

      dn: ou=auto.home,ou=autofs,ou=services,dc=company,dc=com
      ou: auto.home
      objectClass: top
      objectClass: automountMap

      dn: cn=/,ou=auto.home,ou=autofs,ou=services,dc=company,dc=com
      objectClass: top
      objectClass: automount
      cn: /
      automountInformation: -hard,intr,fsc,timeo=2,retry=5 nas1.company.com:/ex
      port/home/&

      I am able to mount the home folder when '/etc/autofs_ldap_auth.conf' contains:




      but unable to mount anything at all when it contains:



      My '/etc/nsswitch.conf' does specify only to use LDAP when automounting:

      automount: ldap

      My '/etc/default/autofs' does contain 'MASTER_MAP_NAME="/etc/auto.master"' where the file contents of that file are '+auto.master'. I have enabled/disabled this option without it seeming to make any difference, in that simple authentication with 'nssproxy' mounts the home folder and GSSAPI fails.

      An 'ldapwhoami' appears to use SASL correctly:

      jerry@test3:/$ ldapwhoami
      SASL/GSSAPI authentication started
      SASL username: jerry@COMPANY.COM
      SASL SSF: 56
      SASL data security layer installed.
      dn:uid=jerry,cn=company.com,cn=gssapi,cn=auth

      Here's my keytab:

      jerry@test3:/$ sudo klist -k
      Keytab name: FILE:/etc/krb5.keytab
      KVNO Principal
      ---- --------------------------------------------------------------------------
      2 host/test3.company.com@COMPANY.COM
      2 host/test3.company.com@COMPANY.COM
      2 host/test3.company.com@COMPANY.COM
      2 host/test3.company.com@COMPANY.COM
      2 autofsclient/test3.company.com@COMPANY.COM
      2 autofsclient/test3.company.com@COMPANY.COM
      2 autofsclient/test3.company.com@COMPANY.COM
      2 autofsclient/test3.company.com@COMPANY.COM


      Thanks again. Jerry.

      Delete
    8. Hello Jerry,

      Hummm, I'm not sure what the -ghost option does. And I'm quite sure you would prefer to remove the -hard option as well. And from my experience, I'm not sure you need the ampersand in your OpenLDAP automount entries. Try removing it, restart the automount daemon and see if you can mount now?

      We haven't talked about the /etc/autofs_ldap_auth.conf file. What does your file contains? This is Kerberos version :





      And here's a simple bind version with the encrypted password :






      And here's the sysconfig autofs file :

      # /etc/sysconfig/autofs
      #
      # $Id: autofs,v 1.1 2012/05/17 15:11:45 root Exp $
      #
      # System-wide autofs(8) daemon configuration.
      #
      # David Robillard, May 15th, 2012.

      MASTER_MAP_NAME="auto.master"
      TIMEOUT=300
      BROWSE_MODE="no"
      MOUNT_NFS_DEFAULT_PROTOCOL=4
      # Change LOGGING to "none" for production.
      LOGGING="verbose"
      LDAP_URI="ldap://ldap1.example.com"
      SEARCH_BASE="ou=autofs,ou=services,dc=example,dc=com"
      MAP_OBJECT_CLASS="automountMap"
      ENTRY_OBJECT_CLASS="automount"
      MAP_ATTRIBUTE="ou"
      ENTRY_ATTRIBUTE="cn"
      VALUE_ATTRIBUTE="automountInformation"
      USE_MISC_DEVICE="yes"

      # EOF

      As you can see, the MASTER_MAP_NAME is not "/etc/auto.master", but simply "auto.master".

      You might want to check your keyfile entries with what's in the KDC in order to make sure they are all at the same KVNO (Key Version Number). Like so (See the « Key: vno 2 » lines) :

      sudo kadmin -p davidr/admin@EXAMPLE.COM
      Authenticating as principal davidr/admin@EXAMPLE.COM with password.
      Password for davidr/admin@EXAMPLE.COM:
      kadmin:
      kadmin: getprinc autofsclient/jedi.example.com@EXAMPLE.COM
      Principal: autofsclient/jedi.example.com@EXAMPLE.COM
      Expiration date: [never]
      Last password change: Thu Oct 24 14:16:49 EDT 2013
      Password expiration date: [none]
      Maximum ticket life: 1 day 00:00:00
      Maximum renewable life: 0 days 00:00:00
      Last modified: Thu Oct 24 14:16:49 EDT 2013 (davidr/admin@EXAMPLE.COM)
      Last successful authentication: [never]
      Last failed authentication: [never]
      Failed password attempts: 0
      Number of keys: 6
      Key: vno 2, aes256-cts-hmac-sha1-96, Version 5
      Key: vno 2, aes128-cts-hmac-sha1-96, Version 5
      Key: vno 2, des3-cbc-sha1, Version 5
      Key: vno 2, arcfour-hmac, Version 5
      Key: vno 2, des-hmac-sha1, Version 5
      Key: vno 2, des-cbc-md5, Version 5
      MKey: vno 1
      Attributes:
      Policy: [none]

      Last, but not least, make sure your Kerberos machines and your client machines are all in sync via NTP. If they're not, nothing will work. Make sure all machines have a working copy of the /etc/ntp.conf file and try this on all of them :

      sudo /etc/init.d/ntpd stop
      sudo ntpdate 0.ca.pool.centos.org # Or your own NTP servers.
      sudo /etc/init.d/start

      Wait a while. NTP takes a long time to sync. Could be up to 10 minutes. Then check the status :

      ntpq -p
      remote refid st t when poll reach delay offset jitter
      ==============================================================================
      *jedi.example.com 129.128.5.210 2 u 301 1024 377 0.159 -0.688 1.485
      +yoda.example.com 171.66.241.4 2 u 348 1024 377 0.149 -2.297 3.739
      LOCAL(0) .LOCL. 10 l 5d 64 0 0.000 0.000 0.000

      The machine that has an « * » in front is the server to which the client is in sync. The other with the « + » is the next available NTP server to sync to.

      Make sure your NTP servers are in sync before you try to sync to them from a client.

      HTH,

      DA+

      Delete
  58. Strange, my two example of /etc/autofs_ldap_auth.conf file have been stripped from my comment. Here's the Kerberos version again without the XML tags :

    autofs_ldap_sasl_conf
    usetls="yes"
    tlsrequired="yes"
    authrequired="yes"
    authtype="GSSAPI"
    clientprinc="autofsclient/jedi.example.com@EXAMPLE.COM"

    HTH,

    David

    ReplyDelete
  59. The same thing happened to me:

    I am able to mount the home folder when '/etc/autofs_ldap_auth.conf' contains:

    usetls="yes"
    tlsrequired="no"
    authrequired="simple"
    user="cn=nssproxy,ou=users,dc=company,dc=com"
    secret="nssproxy"

    but unable to mount anything at all when it contains:

    usetls="yes"
    tlsrequired="yes"
    authrequired="yes"
    authtype="GSSAPI"
    clientprinc="autofsclient/test3.company.com@COMPANY.COM"

    I will play around with and change the mount options in LDAP.

    ReplyDelete
  60. Hi David,

    I think I updated everything according to your suggestions and retried without any luck. On a whim I merged the 'olcDatabase={1}hdb,cn=config' ACLs 3 and 4 to form a single ACL:

    olcAccess: {3}to dn.subtree="dc=company,dc=com"
    by dn.base="cn=admin,dc=company,dc=com" manage
    by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
    by dn.regex="uid=.*/admin,cn=company.com,cn=gssapi,cn=auth" manage
    by dn.exact="cn=krbadmin,ou=users,dc=company,dc=com" write
    by dn.exact="cn=nssproxy,ou=users,dc=company,dc=com" read
    by dn.regex="uid=autofsclient/.*,cn=company.com,cn=gssapi,cn=auth" read
    by * none

    This was an attempt to provide the autofsclient/* Kerberos principals with access to the entire base DN. After restarting my client machine, the automounting worked. I then returned to the separate ACL's but switched their order:

    olcAccess: {3}to dn.subtree="ou=autofs,ou=services,dc=company,dc=com"
    by dn.regex="uid=autofsclient/.*,cn=company.com,cn=gssapi,cn=auth" read

    olcAccess: {4}to dn.subtree="dc=company,dc=com"
    by dn.base="cn=admin,dc=company,dc=com" manage
    by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
    by dn.regex="uid=.*/admin,cn=company.com,cn=gssapi,cn=auth" manage
    by dn.exact="cn=krbadmin,ou=users,dc=company,dc=com" write
    by dn.exact="cn=nssproxy,ou=users,dc=company,dc=com" read
    by * none

    This also worked. Not really being familiar with ACLs, is it possible that the rules of '{3'} (before I made these changes) are overriding/superseding the rules of '{4}'? I did find the site http://www.linuxtopia.org/online_books//network_administration_guides/ldap_administration/slapdconf2_Access_Control.html which might confirm my assumption:

    The following example shows the use of style specifiers to select the entries by DN in two access directives where ordering is significant.
    olcAccess: to dn.children="dc=example,dc=com"
    by * search
    olcAccess: to dn.children="dc=com"
    by * read
    Read access is granted to entries under the dc=com subtree, except for those entries under the dc=example,dc=com subtree, to which search access is granted. No access is granted to dc=com as neither access directive matches this DN. If the order of these access directives was reversed, the trailing directive would never be reached, since all entries under dc=example,dc=com are also under dc=com entries.


    Also, when I removed the ampersand from the 'cn=/,ou=auto.home,ou=autofs,ou=services,dc=company,dc=com
    ' automount information, my home folder mounted funny as '/home/jerry/jerry'. Returning the ampersand yielded just '/home/jerry'.

    Thank you for your help in all of this. Again, your tutorial is the first and only one to get me this far :) Jerry.

    ReplyDelete
    Replies
    1. Hello Jerry,

      Nice, you got it working! :)

      Yeah, the ACLs in OpenLDAP are read from top to bottom. So the idea is to place the most restrive ones on top (or with index number {0}) then open up wider and wider as you go down the list. So in your case, placing a restriction on ou=autofs before the entire directory information tree (DIT) makes a lot of sense. That will allow the autofsclient/* Kerberos principals to get their data from the ou=autofs subtree while other OpenLDAP dn won't have read access to your ou=autofs. Which is sound security practices.

      And if your curious to learn more about OpenLDAP access control, the URL you posted is simply a copy of the official OpenLDAP documentation on this :

      http://www.openldap.org/doc/admin24/access-control.html

      Finally, about the ampersand, I think my configuration identifies the mount point as /nfs and then in there you can either mount /home or /install as in /nfs/home and /nfs/install. So when a user's home is set to /nfs/home/davidr for instance, then the automounter will mount /nfs/home and won't try to mount /nfs/home/davidr.

      In your case, the mount point is set /home and the username is the actual directory that is being mounted by the automounter. In this way, the directory set for the user is /home/jerry. So that when you login, the moint point is /home/jerry. Do you see the difference?

      This is a design choice of course. Your setup works just as good as mine. But there's a subtle difference. If you set a corporate network with thousands of users with your configuration, then each time one of them connects to a server, then the automounter has to request a specific direectory from the NFS server. Which means that if we both login to the same box, we would each have our own NFS mounted file system. If, on the other hand, you setup the same corporate network with a setup like mine, then if there is a single or a thousand users connected to the same machine, there's only a single NFS call being done for all of them.

      As an example, let's say we're both connected on the same machine with my setup, then this is what we see :

      [davidr@yoda:ldap2] ~ {1004}$ df -ht nfs
      Filesystem Size Used Avail Use% Mounted on
      nfs1.example.com:/export/home 296G 92G 189G 33% /nfs/home

      But, if we used your setup, then this is what we would see :

      [davidr@yoda:ldap2] ~ {1004}$ df -ht nfs
      Filesystem Size Used Avail Use% Mounted on
      nfs1.example.com:/export/home/davidr 296G 92G 189G 33% /home/davidr
      nfs1.example.com:/export/home/jerrry 296G 92G 189G 33% /home/jerry

      Now try to scale this in your imagination. How many NFS mounts can your NFS server really perform? How many NFS mounts can the client do? When does this all comes crashing down because of too many NFS traffic? It's a simple question of managing the resources of both the client and the NFS server.

      Or course, if you're building the OpenLDAP and NFS setup in your home for fun, then both work equaly well :)

      HTH,

      David

      Delete
    2. Hi David,

      That helps me better understand ACLs and the implications of using the two NFS 'home' approaches. I didn't fully understand the overhead differences when choosing my direction, but your way looks better.

      I am seeking to configure the client system for mitigating the user home folder availability automatically. Maybe this would mean to cache the user's NFS home data to the client file system. If the NFS mount is unavailable, then the user would automatically access the local copies. Otherwise, the NFS location would be used and the local folder synchronized. However, I don't have enough information yet to understand if my expectations are reasonable. Do you know if this is a valid setup and, if so, an available solution?

      Otherwise, this is all I can come up with:

      The machine 'nas1' is the network-attached storage device and exports '/export/home'.

      The client machine 'test3' caches/mirrors the user's NFS home data to the local file system at '/home/'.

      The client machine's '/etc/fstab' mounts '/home' over '/nfs/home'.

      The user's LDAP account has 'homeDirectory' set to '/nfs/home/', which is where the user should access its data.

      If the network share becomes available, then 'nas1:/export/home' is mounted at 'test3:/nfs/home' (not sure what any of that would imply for files already open on the local user folder).

      I was hoping CacheFS would synchronize the NFS and local locations but the only information I could find suggests no. It is also unclear unclear to me if a machine associated with a particular user (like my laptop to me) can or should have a local account with the same user name, UID and/or GUID. This is getting off topic a bit from just the AutoFS but the questions seem to fit with the SSO approach.

      Any information you can provide is appreciated.

      Thanks. Jerry.

      Delete
  61. Hello David,

    I made a mistake when it was time to make a full backup on destination path so no backup exist and of course I encountered an other mistake chen I tryed to new gssapi.acl.ldif (on most important one I think :
    dn: olcDatabase={0}config,cn=config
    changetype: modify
    delete: olcAccess
    olcAccess: {0}

    and now I'm not more able to modify anything....

    I decided to stop slapd service and to restore /etc/openldap/slapd.d/cn=config/olcDatabase={0}config.ldif from an old backup which contains deleted olcAccess....

    I hope I'm clear.....

    but my problem is when I try to restart slapd service, I got this error :
    Vérification des fichiers de configuration pour slapd : [ÉCHOUÉ]
    PROXIED attributeDescription "DC" inserted.
    ldif_read_file: Permission denied for "/etc/openldap/slapd.d/cn=config/olcDatabase={0}config.ldif"
    slaptest: bad configuration file!

    I verified cn=config folder with that :
    $ ls -l /etc/openldap/slapd.d/cn=config/total 72
    drwxrwxr-x. 2 ldap ldap 4096 6 avril 22:51 cn=schema
    -rw-------. 1 ldap ldap 51896 23 mars 20:14 cn=schema.ldif
    -rw-------. 1 ldap ldap 653 25 avril 21:39 olcDatabase={0}config.ldif
    -rw-------. 1 ldap ldap 1961 23 avril 22:42 olcDatabase={1}bdb.ldif
    -rw-------. 1 ldap ldap 525 23 mars 20:14 olcDatabase={-1}frontend.ldif
    -rw-------. 1 ldap ldap 620 23 mars 20:14 olcDatabase={2}monitor.ldif
    and everything seems to be ok in terms of owner and privileges...

    How can I repair ?

    In advance, thanks for your help,

    Fredouille
    berok37@hotmail.com

    ReplyDelete
  62. Hello Fredouille,

    Are you running SELinux? Maybe that's causing the issue. Try running this command :

    sudo selinuxenabled
    echo $?

    If the number is zero, then SELinux is enabled. If it's a 1, then it's not.

    If it's running, verify the SELinux security context on the files with the -Z switch to the ls command. Or you can simply turn SELinux off then reboot.

    Or you might have file ACLs in place. Check to see if you have « acl » listed in the mount command?

    HTH,

    DA+

    ReplyDelete
    Replies
    1. Hello David,

      Thanks a lot for your help,

      I have changed Selinux security context on /etc/openldap/slapd.d/cn=config/olcDatabase={0}config.ldif and service slapd accepted to restart....

      Again Thank you very much

      Bye,

      Fredouille,

      Delete
    2. that's incredible,

      I tryed to implement again new gssapi.acl.ldif, exactly same as yours exept about Domain and Realm names, and again it's impossible to modify anything more after first deleting olcAccess on dn: olcDatabase={0}config,cn=config....

      Really I understand why but I don't see how to modify without error...

      Again, Can you help me ??

      Thanks,

      Fredouille

      Delete
    3. I found a solution to implement new ACLs as described and check with "ldapsearch -xLLLZWD cn=admin,dc=company,dc=com -b cn=config olcAccess" and all news ACLs were in right place so I decided to reboot server and now there are some wrong things I think :

      krb5kdc and kadmin services don't start during boot, so I checked logs files :

      about krb5kdc.log :
      Invalid credentials - while initializing database for realm .......

      about kadmin.log :
      Invalid credentials - while initializing, aborting

      about secure :
      sudo: pam_krb5[4365]: account checks fail for 'fredouille': KDCs are unreacheable
      Cannot contact any KDC for requested realm)

      Can you help me please ?

      Thanks in advance,

      Fredouille,

      Delete
  63. Hello David,

    about SELinux (impossible to use sudo, so) :
    su -c 'selinuxenabled; echo $?'
    Mot de passe :
    0

    about SELinux context, I have :
    ls -Zl /etc/openldap/slapd.d/cn=config/total 72
    drwxrwxr-x. 2 unconfined_u:object_r:slapd_db_t:s0 ldap ldap 4096 6 avril 22:51 cn=schema
    -rw-------. 1 unconfined_u:object_r:slapd_db_t:s0 ldap ldap 51896 23 mars 20:14 cn=schema.ldif
    -rw-------. 1 unconfined_u:object_r:user_home_t:s0 ldap ldap 653 25 avril 21:39 olcDatabase={0}config.ldif
    -rw-------. 1 system_u:object_r:slapd_db_t:s0 ldap ldap 1961 23 avril 22:42 olcDatabase={1}bdb.ldif
    -rw-------. 1 unconfined_u:object_r:slapd_db_t:s0 ldap ldap 525 23 mars 20:14 olcDatabase={-1}frontend.ldif
    -rw-------. 1 unconfined_u:object_r:slapd_db_t:s0 ldap ldap 620 23 mars 20:14 olcDatabase={2}monitor.ldif

    so my mistake seems to be here becaure I have "unconfined_u:object_r:user_home_t:s0" on wrong file..

    And I can't see anything about ACL because slapd service refuse to restart...

    What can I do ??

    Fredouille,

    ReplyDelete
  64. Hello David,

    I don't know why but when I made my first backup (just before modifying gssapi.acl.ldif) on which I made a mistake on my command :
    $ dossier6="/media/TRANSCEND/LDAP-LAN/ldap-srvr/cmds-executees/08-srvr"
    $ sudo tar zcvf $dossiers6/slapd.d.backup.tar.gz /etc/openldap/slapd.d

    Last command was wrong because I wrote $dossiers6 and not $dossier6, well I don't know why but it wrote backup directly on /.....

    Anyway, after long night spent to find a solution to repair, I found backup on / this morning and I decided to restore it.
    So I've done :
    $ sudo service slapd stop
    $ sudo tar -zxvf /slapd.d.backup.tar.gz -C /
    $ sudo shutdown -r now

    During reboot all services started so I can conclude : everything is restored.

    I'm now able to look on ACLs which are in use :
    $ ldapsearch -xLLLZWD cn=admin,dc=berok,dc=org -b cn=config olcAccess
    Enter LDAP Password:
    dn: cn=config
    dn: cn=schema,cn=config
    dn: cn={0}core,cn=schema,cn=config
    dn: cn={1}cosine,cn=schema,cn=config
    dn: cn={2}inetorgperson,cn=schema,cn=config
    dn: cn={3}collective,cn=schema,cn=config
    dn: cn={4}corba,cn=schema,cn=config
    dn: cn={5}duaconf,cn=schema,cn=config
    dn: cn={6}openldap,cn=schema,cn=config
    dn: cn={7}dyngroup,cn=schema,cn=config
    dn: cn={8}java,cn=schema,cn=config
    dn: cn={9}misc,cn=schema,cn=config
    dn: cn={10}nis,cn=schema,cn=config
    dn: cn={11}ppolicy,cn=schema,cn=config
    dn: cn={12}kerberos,cn=schema,cn=config
    dn: cn={13}sudo,cn=schema,cn=config
    dn: cn={14}autofs,cn=schema,cn=config
    dn: olcDatabase={-1}frontend,cn=config
    dn: olcDatabase={0}config,cn=config
    olcAccess: {0}to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=externa
    l,cn=auth" manage by dn.base="cn=admin,dc=berok,dc=org" manage by * none

    dn: olcDatabase={1}bdb,cn=config
    olcAccess: {0}to attrs=userPassword,userPKCS12 by dn.base="gidNumber=0+uidNumb
    er=0,cn=peercred,cn=external,cn=auth" manage by dn.exact="cn=nssproxy,ou=User
    s,dc=berok,dc=org" read by self write by anonymous auth by * none
    olcAccess: {1}to attrs=shadowLastChange by self write by dn.base="gidNumber=0+
    uidNumber=0,cn=peercred,cn=external,cn=auth" manage by dn.exact="cn=nssproxy,
    ou=Users,dc=berok,dc=org" read by * none
    olcAccess: {2}to dn.subtree="ou=kerberos,ou=services,dc=berok,dc=org" by dn.e
    xact="cn=krbadmin,ou=Users,dc=berok,dc=org" write by dn.base="gidNumber=0+uid
    Number=0,cn=peercred,cn=external,cn=auth" read by * none
    olcAccess: {3}to dn.subtree="dc=berok,dc=org" by dn.exact="cn=krbadmin,ou=User
    s,dc=berok,dc=org" write by dn.exact="cn=nssproxy,ou=Users,dc=berok,dc=org" r
    ead by * none

    dn: olcDatabase={2}monitor,cn=config
    olcAccess: {0}to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=externa
    l,cn=auth" manage by dn.base="cn=admin,dc=berok,dc=org" manage by * none

    I found an other of my mistake on my gssapi.acl.ldif about uppercase/lowercase on OU.

    Does uppercase/lowercase important or not ?

    Now I'm a little afraid when I need to modify ACLs....

    You will find below my gssapi.acl.ldif :
    # gssapi.acl.ldif
    #
    # Specify ACLs for use with SASL GSSAPI Kerberos.
    # We will work on three different dn:
    #
    # First on dn: olcDatabase={0}config,cn=config
    # Second on dn: olcDatabase={1}bdb,cn=config
    # Third on dn: olcDatabase={2}monitor,cn=config

    dn: olcDatabase={0}config,cn=config
    changetype: modify
    add: olcAccess
    olcAccess: {1}to *
    by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
    by dn.base="cn=admin,dc=berok,dc=org" manage
    by dn.regex="uid=.*/admin,cn=berok.org,cn=gssapi,cn=auth" manage
    by * none

    (Spliting in 2 posts due to size limitation)

    Fredouille,

    ReplyDelete
  65. 2nd post :

    dn: olcDatabase={0}config,cn=config
    changetype: modify
    add: olcAccess
    olcAccess: {2}to attrs=userPassword,shadowLastChange
    by dn.regex="uid=.*/admin,cn=berok.org,cn=gssapi,cn=auth" manage
    by dn.base="cn=admin,dc=berok,dc=org" manage
    by self write
    by dn="cn=nssproxy,ou=Users,dc=berok,dc=org" read
    by * auth
    by * none

    dn: olcDatabase={0}config,cn=config
    changetype: modify
    delete: olcAccess
    olcAccess: {0}

    ##
    # We switch our work to the Berkeley DB backend database.
    ##

    # Allow Kerberos /admin principals to manage user passwords.
    dn: olcDatabase={1}bdb,cn=config
    changetype: modify
    add: olcAccess
    olcAccess: {4}to attrs=userPassword,userPKCS12
    by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
    by dn.base="cn=admin,dc=berok,dc=org" manage
    by dn.regex="uid=.*/admin,cn=berok.org,cn=gssapi,cn=auth" manage
    by dn.exact="cn=nssproxy,ou=Users,dc=berok,dc=org" read
    by self write
    by anonymous auth
    by * none

    # Allow Kerberos /admin principals to manage user passwords.
    dn: olcDatabase={1}bdb,cn=config
    changetype: modify
    add: olcAccess
    olcAccess: {5}to attrs=shadowLastChange
    by self write
    by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
    by dn.base="cn=admin,dc=berok,dc=org" manage
    by dn.regex="uid=.*/admin,cn=berok.org,cn=gssapi,cn=auth" manage
    by dn.exact="cn=nssproxy,ou=Users,dc=berok,dc=org" read
    by * none

    # Allow Kerberos /admin principals to see the Kerberos container, but not change it.
    # This will force administration of the Kerberos realm with Kerberos tools.
    dn: olcDatabase={1}bdb,cn=config
    changetype: modify
    add: olcAccess
    olcAccess: {6}to dn.subtree="ou=kerberos,ou=services,dc=berok,dc=org"
    by dn.exact="cn=krbadmin,ou=Users,dc=berok,dc=org" write
    by dn.regex="uid=.*/admin,cn=berok.org,cn=gssapi,cn=auth" read
    by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" read
    by dn.base="cn=admin,dc=berok,dc=org" read
    by * none

    # Allo */admin principals to manage this OpenLDAP server.
    # This will be used with Apache Directory Studio.
    dn: olcDatabase={1}bdb,cn=config
    changetype: modify
    add: olcAccess
    olcAccess: {7}to dn.subtree="dc=berok,dc=org"
    by dn.base="cn=admin,dc=berok,dc=org" manage
    by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
    by dn.regex="uid=.*/admin,cn=berok.org,cn=gssapi,cn=auth" manage
    by dn.exact="cn=krbadmin,ou=Users,dc=berok,dc=org" write
    by dn.exact="cn=nssproxy,ou=Users,dc=berok,dc=org" read
    by * none

    # Allow the autofsclient/* Kerberos principals to see the contents of
    # the automount maps.
    dn: olcDatabase={1}bdb,cn=config
    changetype: modify
    add: olcAccess
    olcAccess: {8}to dn.subtree="ou=autofs,ou=services,dc=berok,dc=org"
    by dn.regex="uid=autofsclient/.*,cn=berok.org,cn=gssapi,cn=auth" read
    by * none

    dn: olcDatabase={1}bdb,cn=config
    changetype: modify
    delete: olcAccess
    olcAccess: {0}

    dn: olcDatabase={1}bdb,cn=config
    changetype: modify
    delete: olcAccess
    olcAccess: {1}

    dn: olcDatabase={1}bdb,cn=config
    changetype: modify
    delete: olcAccess
    olcAccess: {2}

    dn: olcDatabase={1}bdb,cn=config
    changetype: modify
    delete: olcAccess
    olcAccess: {3}

    ##
    # Now we switch to dn: olcDatabase={2}monitor,cn=config
    ##
    #

    dn: olcDatabase={2}monitor,cn=config
    changetype: modify
    add: olcAccess
    olcAccess: {1}to *
    by dn.base="cn=admin,dc=berok,dc=org" manage
    by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
    by dn.regex="uid=.*/admin,cn=berok.org,cn=gssapi,cn=auth" manage
    by * none

    dn: olcDatabase={2}monitor,cn=config
    changetype: modify
    delete: olcAccess
    olcAccess: {0}

    Can you help me please ??

    Thanks a lot in advance,

    Fredouille,
    berok37@hotmail.com

    ReplyDelete
  66. Hello David,

    I tryed to modify gssapi.acl.ldif and this time that seems to be ok in terms of ldif....

    When I check if the RootDN can still see the configuration with ldapsearch -xLLLZWD cn=admin,dc=berok,dc=org -b cn=config -s base dn, I have :
    "Enter LDAP Password:
    dn: cn=config" as you said.
    When I check if a user with both UID and GID set to zero can see the configuration with sudo ldapsearch -LLLY EXTERNAL -H ldapi:/// -b cn=config -s base dn, I have :
    "sudo: ldap_sasl_bind_s(): Invalid credentials
    Mot de passe :
    SASL/EXTERNAL authentication started
    SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
    SASL SSF: 0
    dn: cn=config"

    So I think I have a mistake with ldap_sasl_bind while command still give good result...

    How can I repair this, please ?

    If I continu and check if a /admin principal has access to the configuration, I have :
    "kdestroy
    kdestroy: No credentials cache found while destroying cache
    kinit -p fredouille/admin@BEROK.ORG
    Password for fredouille/admin@BEROK.ORG:
    ldapsearch -LLLZb cn=config -s base dn
    SASL/GSSAPI authentication started
    SASL username: fredouille/admin@BEROK.ORG
    SASL SSF: 56
    SASL data security layer installed.
    dn: cn=config"

    It seems to work...

    But when I check if the cn=nssproxy user can still work with ldapsearch -xZLLLWD cn=nssproxy,ou=Users,dc=berok,dc=org -b dc=berok,dc=org dn, I have :
    "Enter LDAP Password:
    ldap_bind: Invalid credentials (49)"

    It doesn't work....

    How can I repair ?

    Thanks for your help,

    Fredouille,
    berok37@hotmail.com

    ReplyDelete
  67. Hi David,

    there is no ou=services,dc=company,dc=com, so when I want to execute

    ldapmodify -x -D cn=admin,dc=vsbtest,dc=cz -W -f /etc/ldap/kerberos.ldif
    Enter LDAP Password:
    ldapmodify: modify operation type is missing at line 2, entry "ou=kerberos,ou=services,dc=vsbtest,dc=cz"


    and if I do following:


    root@kerberos:/etc/ldap# ldapadd -x -D cn=admin,dc=vsbtest,dc=cz -W -f /etc/ldap/kerberos.ldif
    Enter LDAP Password:
    adding new entry "ou=kerberos,ou=services,dc=vsbtest,dc=cz"
    ldap_add: No such object (32)
    matched DN: dc=vsbtest,dc=cz


    Can you please write where have you add ou=services... in which step?
    Thank you!
    M

    ReplyDelete
    Replies
    1. Hey!

      The container is created with the kerberos.ldif file :
      https://dl.dropboxusercontent.com/u/72609528/blog/openldap/kerberos.ldif

      HTH,

      DA+

      Delete
    2. David,
      thank you for your reply.

      However, now I have problem with using kadmin with admin principals:
      sudo kadmin -p miralem/admin@VSBTEST.CZ

      will fail because of
      kadmin: Communication failure with server while initializing kadmin interface

      and in my log file I have:
      $
      Jun 17 12:00:26 kerberos krb5kdc[2430](info): AS_REQ (4 etypes {18 17 16 23}) 192.168.56.102: SERVER_NOT_FOUND: miralem/admin@VSBTEST.CZ fo$
      Jun 17 12:00:26 kerberos krb5kdc[2430](info): AS_REQ (4 etypes {18 17 16 23}) 192.168.56.102: ISSUE: authtime 1402999226, etypes {rep=18 tk$

      Can you please give me some advice?

      Tnx,
      M

      Delete
  68. David,

    the best answer on my stupid question is just to turn on kadmin :)
    http://mehic.info/2014/06/kerberos-communication-failure-with-server-while-initializing-kadmin-interface/

    However, thank you for great tutorial!
    Miralem

    ReplyDelete
  69. Hi David,
    Your blog about openldap and kerberos is excellent, very good and detailed steps.

    I have some basic question, can you please answer below.

    After we populate the kerberos container with all the kerberos principals during the process of setting up the configuration as LDAP as principal repository for Kerberos using kdb_ldap_util command.

    How we will add the kerberos principals to the ldap which are created subsequently.

    Thanks for your help

    ReplyDelete
    Replies
    1. Hey thanks for the good words.

      With regards to Kerberos, you have to treat OpenLDAP as a simple database. You don't use OpenLDAP commads or GUI browsers to update Kerberos data. It's simply that the Kerberos realm's data is stored within OpenLDAP and leverages it's replication capacity.

      To add or remove Kerberos principals, use the kadmin interface.

      sudo kadmin -p user/admin@REALM

      Then type ? to see what commands are available to you. Most can use a regex. Such as getprincs host/* for example.

      HTH,

      David

      Delete
  70. Got it , thanks David for your quick reply, I really appreciate it.

    ReplyDelete
    Replies
    1. Sure, no problem. There's a few examples of the kadmin command in this page. You'll notice that the first principals are added with the kadmin.local command. This one only works when you're logged in the KDC (hence the .local name, which hints at localhost).

      As with anything with Kerberos, make sure your NTP is working. It will save you hours of frustrating debug sessions :)

      Let me know if you run into other issues.

      Cheers,

      David

      Delete
  71. Hi David,
    Thanks for your earlier responses about kerberos on this page on Nov 14/15th.
    Actually I have openldap configured for 'bdb' database, TLS enabled and working fine. Also have Kerberos install done, working fine. I am planning to have openldap as repository for Kerberos, that's why I asked earlier questions.
    I am following your blog for this exercise.

    Started cn=config configuration, completed slaptest steps successfully. Now everything set under /etc/openldap/slapd.d

    -rw------- 1 ldap ldap 1249 Nov 17 10:57 cn=config.ldif
    drwxr-x--- 3 ldap ldap 4096 Nov 17 10:57 cn=config
    [root@master slapd.d]# cd cn=config
    [root@master cn=config]# ls -ltr
    total 72
    -rw------- 1 ldap ldap 51896 Nov 17 10:57 cn=schema.ldif
    drwxr-x--- 2 ldap ldap 4096 Nov 17 10:57 cn=schema
    -rw------- 1 ldap ldap 728 Nov 17 10:57 olcDatabase={1}monitor.ldif
    -rw------- 1 ldap ldap 525 Nov 17 10:57 olcDatabase={-1}frontend.ldif
    -rw------- 1 ldap ldap 668 Nov 17 10:57 olcDatabase={0}config.ldif
    -rw------- 1 ldap ldap 2702 Nov 17 10:57 olcDatabase={2}bdb.ldif

    bdb - details

    database bdb
    suffix "dc=xxxxx,dc=com"
    checkpoint 1024 15
    rootdn "cn=Manager,dc=xxxxxx,dc=com"

    As I said above, my bdb config is working fine, have everything ready including users, group,
    and I am getting objects using ldapsearch command - no issues here
    ldapsearch -xLLLWD cn=Manager,dc=xxxxxx,dc=com -b dc=xxxxxx,dc=com
    Enter LDAP Password:

    cn=config -details
    # enable on-the-fly configuration (cn=config)
    database config
    rootdn "cn=manager,cn=config"

    I am not able to see cn=config suffix, I am getting No such object exception for the below ldapsearch command

    ldapsearch -xLLLWD cn=manager,dc=xxxxxx,dc=com -b cn=config dn
    Enter LDAP Password:
    No such object (32)

    CAN YOU PLEASE LET ME KNOW WHAT I AM MISSING ON THE ABOVE

    fyi, I am able to see cn=config suffix using ldapsearch below.

    ldapsearch -LLL -Y EXTERNAL -H ldapi:/// -b cn=config dn

    SASL/EXTERNAL authentication started
    SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
    SASL SSF: 0
    dn: cn=config

    dn: cn=schema,cn=config

    dn: cn={0}corba,cn=schema,cn=config

    dn: cn={1}core,cn=schema,cn=config

    dn: cn={2}cosine,cn=schema,cn=config

    dn: cn={3}duaconf,cn=schema,cn=config

    dn: cn={4}dyngroup,cn=schema,cn=config

    dn: cn={5}inetorgperson,cn=schema,cn=config

    dn: cn={6}java,cn=schema,cn=config

    dn: cn={7}misc,cn=schema,cn=config

    dn: cn={8}nis,cn=schema,cn=config

    dn: cn={9}openldap,cn=schema,cn=config

    dn: cn={10}ppolicy,cn=schema,cn=config

    dn: cn={11}collective,cn=schema,cn=config

    dn: cn={12}kerberos,cn=schema,cn=config

    dn: cn={13}schema,cn=schema,cn=config

    dn: olcDatabase={-1}frontend,cn=config

    dn: olcDatabase={0}config,cn=config

    dn: olcDatabase={1}monitor,cn=config

    dn: olcDatabase={2}bdb,cn=config

    Please let me know if you require any more info or configs for further help and guidance.

    Thanks a lot for your help.

    SS

    ReplyDelete
  72. Hello SS,

    You are authenticating with two different users using two different auth mechanisms. See...

    a) ldapsearch -xLLLWD cn=manager,dc=xxxxxx,dc=com -b cn=config dn
    b) ldapsearch -LLL -Y EXTERNAL -H ldapi:/// -b cn=config dn

    Command a) uses the « cn=manager,dc=xxxxxx,dc=com » user and the SIMPLE authentication mech. While command b) uses the « gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth » user and the SASL auth mech. This user is basically the root Linux user (i.e. UID zero and GID zero).

    I would check your OpenLDAP ACLs. Query you OpenLDAP server to see them.

    As per command b) output in your post, you have a different database setup than mine, so instead of olcDatabase={1}bdb you will need to replace it by olcDatabase={2}bdb. So this command would work :

    sudo ldapsearch -LLLY EXTERNAL -H ldapi:/// -b olcDatabase={2}bdb,cn=config olcAccess

    Check them out. Make a copy of it. Playing with OpenLDAP ACLs is a pain (well any product's ACLs are a pain to setup :)

    Search this blog post for kerberos.acl.ldif and check it's contents. Make sure you DO NOT blindly copy those. As I said, your setup is different than mine (i.e. your olcDatabase={2}bdb,cn=config is different than my olcDatabase={1}bdb,cn=config) .

    Sometimes, I would update my ACLs and the next olcAccess query would return junk characters. I don't know why, but it's a real problem. I had to revert to backup files. Hopefully you don't have this problem.

    HTH,

    David

    ReplyDelete
  73. Thanks for your wonderful explanations about (a) and (b) commands.

    So, am running (b) as root, and I am able to notice cn=config suffix.

    But for (a), as you suggested I ran the command to check ACLs, did not get any entries for olcAccess
    No olcAccess entried in that olcDatabase={2}bdb
    Fyi, I am running all commands as 'root'

    ldapsearch -LLLY EXTERNAL -H ldapi:/// -b olcDatabase={2}bdb,cn=config olcAccess
    SASL/EXTERNAL authentication started
    SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
    SASL SSF: 0
    dn: olcDatabase={2}bdb,cn=config

    Pl let me know if you require more information.
    Thanks a lot for your time and help.

    Regards,
    SS

    ReplyDelete
    Replies
    1. Hello again SS,

      Try a more broad query for olcAccess then. You previous command « ldapsearch -LLL -Y EXTERNAL -H ldapi:/// -b cn=config dn » results in quite a few dn: showing. The last ones are :


      dn: olcDatabase={-1}frontend,cn=config

      dn: olcDatabase={0}config,cn=config

      dn: olcDatabase={1}monitor,cn=config

      dn: olcDatabase={2}bdb,cn=config

      These are the four databases actually in use by your OpenLDAP server. Each of them might have ACLs applied to them. Try a query for olcAccess on each of them. See what you got?

      HTH,

      DA+

      Delete
  74. Hi David,

    Out of four databases, ACLs applied to only two, config and monitor as below.
    ldapsearch -LLLY EXTERNAL -H ldapi:/// -b olcDatabase={1}monitor,cn=config olcAccess
    SASL/EXTERNAL authentication started
    SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
    SASL SSF: 0
    dn: olcDatabase={1}monitor,cn=config
    olcAccess: {0}to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=externa
    l,cn=auth" read by dn.base="cn=manager,dc=xxxxx,dc=com" read by * none
    olcAccess: {1}to attrs=shadowLastChange,userPassword by self write by * auth
    olcAccess: {2}to * by * read

    ldapsearch -LLLY EXTERNAL -H ldapi:/// -b olcDatabase={0}config,cn=config olcAccess
    SASL/EXTERNAL authentication started
    SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
    SASL SSF: 0
    dn: olcDatabase={0}config,cn=config
    olcAccess: {0}to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=externa
    l,cn=auth" manage by * none

    I tried to apply ACLs to bdb database, but got 'ldap_modify: Insufficient access (50)'

    Below is the ldif and output

    [root@master openldap]# cat access-bdb.ldif
    dn: olcDatabase={2}bdb,cn=config
    changetype: modify
    #
    add: olcAccess
    olcAccess: {0}to *
    by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
    -
    add: olcAccess
    olcAccess: {1}to attrs=userPassword
    by self write
    by * auth
    -
    add: olcAccess
    olcAccess: {2}to dn.base="dc=xxxxxx,dc=com"
    by * search
    by * none

    I checked olcDatabase={2}bdb.ldif, olcRootDN: cn=Manager,dc=centos,dc=com

    [root@master openldap]# ldapmodify -xZWD cn=Manager,dc=xxxxxx,dc=com -f access-bdb.ldifldap_start_tls: Operations error (1)
    additional info: TLS already started
    Enter LDAP Password:
    modifying entry "olcDatabase={2}bdb,cn=config"
    ldap_modify: Insufficient access (50)

    When you get a chance, can you please help me to fix this.

    Thanks
    SS

    ReplyDelete
    Replies
    1. Hello SS,

      Here are the ACLs I have in place in the various databases. Hopefully that will help you set your own.

      -- This is the first database :

      [davidr@host] ~ {1004}$ ldapsearch -LLL -b olcDatabase={0}config,cn=config olcAccess
      SASL/GSSAPI authentication started
      SASL username: davidr/admin@EXAMPLE.COM
      SASL SSF: 56
      SASL data security layer installed.
      dn: olcDatabase={0}config,cn=config
      olcAccess: {0}to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=externa
      l,cn=auth" manage by dn.base="cn=admin,dc=example,dc=com" manage by dn.re
      gex="uid=.*/admin,cn=example.com,cn=gssapi,cn=auth" manage by * none

      As you can see, the only people that can manage this one is the root user (when you authenticate using sudo), the OpenLDAP manager and the Kerberos /admin principals. Anybody else can't even query this database.

      -- The second database :

      [davidr@host] ~ {1011}$ ldapsearch -LLL -b olcDatabase={1}bdb,cn=config olcAccess
      SASL/GSSAPI authentication started
      SASL username: davidr/admin@EXAMPLE.COM
      SASL SSF: 56
      SASL data security layer installed.
      dn: olcDatabase={1}bdb,cn=config
      olcAccess: {0}to attrs=userPassword,userPKCS12 by dn.base="gidNumber=0+uidNum
      ber=0,cn=peercred,cn=external,cn=auth" manage by dn.base="cn=admin,dc=example
      ,dc=com" manage by dn.regex="uid=.*/admin,cn=example.com,cn=gssapi,cn=auth
      " manage by dn.base="cn=nssproxy,ou=users,dc=example,dc=com" read by self
      write by dn.regex="replication,ou=users,dc=example,dc=com" read by anony
      mous auth by * none
      olcAccess: {1}to attrs=shadowLastChange by self write by dn.base="gidNumber=
      0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage by dn.base="cn=admin,d
      c=example,dc=com" manage by dn.regex="uid=.*/admin,cn=example.com,cn=gssapi
      ,cn=auth" manage by dn.base="cn=nssproxy,ou=users,dc=example,dc=com" read
      by dn.regex="replication,ou=users,dc=example,dc=com" read by self write by
      * auth by * none
      olcAccess: {2}to dn.subtree="ou=kerberos,ou=services,dc=example,dc=com" by d
      n.exact="cn=krbadmin,ou=users,dc=example,dc=com" write by dn.regex="uid=.*/
      admin,cn=example.com,cn=gssapi,cn=auth" read by dn.base="gidNumber=0+uidNumber
      =0,cn=peercred,cn=external,cn=auth" read by dn.base="cn=admin,dc=example,dc
      =com" read by dn.regex="replication,ou=users,dc=example,dc=com" read by * n
      one
      olcAccess: {3}to dn.subtree="dc=example,dc=com" by dn.base="cn=admin,dc=exam
      ple,dc=com" manage by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=exter
      nal,cn=auth" manage by dn.regex="uid=.*/admin,cn=example.com,cn=gssapi,cn=auth
      " manage by dn.exact="cn=krbadmin,ou=users,dc=example,dc=com" write by dn.e
      xact="cn=nssproxy,ou=users,dc=example,dc=com" read by dn.regex="uid=autofsc
      lient/.*,cn=example.com,cn=gssapi,cn=auth" read by dn.regex="replication,ou=us
      ers,dc=example,dc=com" read by * none

      dn: olcOverlay={0}syncprov,olcDatabase={1}bdb,cn=config

      dn: olcOverlay={1}accesslog,olcDatabase={1}bdb,cn=config

      Delete
    2. Now in that one we have quite a lot more ACLs. What I would suggest is to write them down line by line as it's easier to debug. If we take the above query result, that would be this :

      olcAccess: {0}
      to attrs=userPassword,userPKCS12
      by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
      by dn.base="cn=admin,dc=example,dc=com" manage
      by dn.regex="uid=.*/admin,cn=example.com,cn=gssapi,cn=auth" manage
      by dn.base="cn=nssproxy,ou=users,dc=example,dc=com" read
      by self write
      by dn.regex="replication,ou=users,dc=example,dc=com" read
      by anonymous auth
      by * none

      olcAccess: {1}
      to attrs=shadowLastChange
      by self write
      by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
      by dn.base="cn=admin,dc=example,dc=com" manage
      by dn.regex="uid=.*/admin,cn=example.com,cn=gssapi,cn=auth" manage
      by dn.base="cn=nssproxy,ou=users,dc=example,dc=com" read
      by dn.regex="replication,ou=users,dc=example,dc=com" read
      by self write
      by * auth
      by * none

      olcAccess: {2}
      to dn.subtree="ou=kerberos,ou=services,dc=example,dc=com"
      by dn.exact="cn=krbadmin,ou=users,dc=example,dc=com" write
      by dn.regex="uid=.*/admin,cn=example.com,cn=gssapi,cn=auth" read
      by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" read
      by dn.base="cn=admin,dc=example,dc=com" read
      by dn.regex="replication,ou=users,dc=example,dc=com" read
      by * none

      olcAccess: {3}
      to dn.subtree="dc=example,dc=com"
      by dn.base="cn=admin,dc=example,dc=com" manage
      by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
      by dn.regex="uid=.*/admin,cn=example.com,cn=gssapi,cn=auth" manage
      by dn.exact="cn=krbadmin,ou=users,dc=example,dc=com" write
      by dn.exact="cn=nssproxy,ou=users,dc=example,dc=com" read
      by dn.regex="uid=autofsclient/.*,cn=example.com,cn=gssapi,cn=auth" read
      by dn.regex="replication,ou=users,dc=example,dc=com" read
      by * none

      See how easier it is to understand the ACLs this way?

      Now if you can't reach your own because of restrictions, try working either via sudo and external auth or with the simple bind as the OpenLDAP manager.

      HTH,

      David

      Delete
    3. Thanks David, for your quick response, you are very helpful, sincerely appreciate it.
      Really above info provided by you is very clear now.
      I will try on my end, and will let you know the outcome.
      Is it OK to ask you about the place from where you are responding to our queries.
      I just want to know, so that I dont want to disturb you during the odd hours.

      Regards,
      SS

      Delete
    4. Thanks for asking, but don't worry about it. When you post something, I get an email which I can read in my own time :)

      Delete
  75. Hi David, how are you ?, hope everything is fine.
    I am SS, back again :)
    I took your help with regards to ACL issues end of the last year, I messed up I think, so I started working on openldap freshly again by installing everything and following your steps 1 by 1. I am currently on Kerberos step, having some issues as below.
    ==========================================================================
    [root@master1 ldap]# ldapmodify -xZWD cn=admin,dc=msr,dc=com -f /root/ldap/kerberos.ldif
    Enter LDAP Password:
    ldapmodify: modify operation type is missing at line 2, entry "ou=kerberos,ou=services,dc=msr,dc=com"
    =========================================================================
    Below is the method you have followed
    [root@master1 ldap]# ldapmodify -aH ldapi:/// -f /root/ldap/kerberos.ldif
    SASL/PLAIN authentication started
    Please enter your password:
    I have no idea what password it is expecting

    ==============================================================================

    [root@master1 ldap]# ldapmodify -xZWD cn=admin,dc=msr,dc=com -f /root/ldap/kerberos.ldif
    Enter LDAP Password:
    adding new entry "ou=kerberos,ou=services,dc=msr,dc=com"
    ldap_add: No such object (32)
    matched DN: dc=msr,dc=com
    ==========================================================================
    FYI,
    [root@master1 ldap]# uname -a
    Linux master1.msr.com 2.6.32-504.8.1.el6.x86_64 #1 SMP Wed Jan 28 21:11:36 UTC 2015 x86_64 x86_64 x86_64

    Centos 6.6

    [root@master1 ldap]# rpm -qa | grep openldap
    openldap-servers-2.4.39-8.el6.x86_64
    openldap-2.4.39-8.el6.x86_64
    openldap-clients-2.4.39-8.el6.x86_64

    Also, I have successfully completed TLS portion too and I am also able to complete adding ldif files without any issues before this Kerberos.ldif file, like users,groups and posixAccounts.
    When you get a chance, can you please look into ldapmodify step for kerberos.ldif
    Please let me know , if you need any more information.

    Regards,
    SS

    ReplyDelete
    Replies
    1. Hey SS,

      I've written a super nice reply for you and for some unknown reason, blogger didn't take it :(

      I'll write again, but later, ok? :)

      Cheers,

      DA+

      Delete
    2. Hello again,

      So, for the first two ldapmodify queries, the difference is in which user is actually trying to authenticate to OpenLDAP. The queries are:

      a) ldapmodify -xZWD cn=admin,dc=msr,dc=com -f /root/ldap/kerberos.ldif
      b) ldapmodify -aH ldapi:/// -f /root/ldap/kerberos.ldif

      Query a) authenticates as the OpenLDAP admin user via simple authentication. The admin in your case is « cn=admin,dc=msr,dc=com ».

      Query b) authenticates as the root user of the Linux machine. Which, in OpenLDAP language, is represented in the ACLs as « gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth »

      The issue with query a) is that the kerberos.ldif file does not specify any ldapmodify commands. So it should be used with the ldapadd command instead. My bad if my blog says otherwise!

      As for query b) I don't know what password it's expecting? Sorry!

      Delete
    3. Now, for the following query and error:

      ldapmodify -xZWD cn=admin,dc=msr,dc=com -f /root/ldap/kerberos.ldif
      Enter LDAP Password:
      adding new entry "ou=kerberos,ou=services,dc=msr,dc=com"
      ldap_add: No such object (32)

      I believe that is due to the fact that your OpenLDAP server might not have the ou=services,dc=msr,dc=com "directory" or leaf-node. Can you check that it exists?

      HTH,

      David

      Delete
    4. Hi David,
      Thanks for your prompt responses.
      Yes, you are right, ou=services is not there, I created first ou=services, and next I was successfully completed adding kerberos ou.
      Next, you have mentioned that you have written a 'super nice reply' for me.
      Did I miss anything, or those nice replies are the two replies you have posted for me.

      Thanks again
      SS

      Delete
  76. Hello, David!

    Could you please explain why you have used
    in kerberos.acl.ldif (the last ACL directive there):

    olcAccess: {3}to dn.subtree="dc=company,dc=com"
    by dn.exact="cn=krbadmin,ou=users,dc=company,dc=com" write
    by dn.exact="cn=nssproxy,ou=users,dc=company,dc=com" read
    by * none

    effectively giving the kerberos services (the kdc and kadmin) write access to the entire DIT?

    Shouldn't it be:

    olcAccess: {3}to dn.subtree="ou=kerberos,dc=company,dc=com"

    ?

    It even stated explicetely in etc.krb5.server.conf:

    ldap_kdc_dn = cn=krbadmin,ou=users,dc=company,dc=com
    # this object needs to have read rights on
    # the realm container, principal container and realm sub-trees
    ldap_kadmind_dn = cn=krbadmin,ou=users,dc=company,dc=com
    # this object needs to have read and write rights on
    # the realm container, principal container and realm sub-trees

    BTW, is there any specific reason you've put KDC config (setting up the ldap db module) into /etc/krb5.conf rather than kdc.conf? I've found people do this either way, but the latter one looks more logical to me. The KDC configured by kdc.conf after all (while krb5.conf left for client conf only). And it is so on MIT kerberos website.

    Also, presently, the kerberos schema requiers the container in which the realms are created to be of krbContainer ObjectClass and referred to as cn=kerberos,dc=example,dc=org (note CN= instead of OU=)
    There's a corresp. bug on ubuntu's launchpad which in turn references a discussion on MIT mailing list

    Yet again thank you for this series, it got me started with LDAP and Kerberos.

    ReplyDelete
    Replies
    1. Hello Anonymous,

      You are right about the krbadmin ACL, it does indeed have more access than it really should. Good catch! I'll update my blog to fix this. Thanks!

      David

      Delete
    2. And for the kdc.conf vs. krb5.conf, I honestly simply never had issues with it, so I've never dug out more info on that. I *think* the first time I tried to set things up, the default krb5.conf file had an example LDAP module configuration. But in any case, I guess there's more than one way to do it :) It sure does make sense to use kdc.conf for the KDC and leave krb5.conf for the client, I agree.

      Then for the CN= vs. OU= conversation, if I check my own OpenLDAP servers, they do indeed use CN= as a krbContainer ObjectClass, but it's buried one step « down » if you'd like. To say this another way, I've decided to setup a ou=kerberos so that things look cleaner when you use an LDAP browser (such as Apache Directory Studio for example). So the kerberos admin has access to the entire subtree of...

      ou=kerberos,ou=services,dc=example,dc=com

      ...but the *real* Kerberos data is located in...

      cn=EXAMPLE.COM,ou=kerberos,ou=services,dc=example,dc=com

      ...where cn=EXAMPLE.COM is in fact cn=REALM.COM and is, indeed, a krbRealmContainer (structural) Object Class :)

      Makes sense?

      HTH,

      DA+

      Delete
  77. Hi David!
    Thanks for the answers, it's nice to hear from you.

    As a side note, I have to say that I find ADS really clunky and unergonomic, though my dislike stems from it basically being Eclipse.) And though I'm not a big fan of web GUIs either (yes I'm picky :) I've found phpLDAPadmin way more adequate.

    BTW the last comment to the first article is also mine.)

    ReplyDelete
  78. Hi David,
    Great article. I was trying to see config files but looks like all dropbox links are broken. Would appreciate if you can fix it. I have my current setup running, but I want to check if user needs to maintain separate password for kerberos and LDAP or passwd will change password for ldap and kerberos both for a specific user.

    ReplyDelete
    Replies
    1. Hey I'm sorry, Dropbox changed their public sharing permissions and I must admit I have not yet updated the links. Will try to do so by the end of this week.

      Thanks for the support,

      David

      Delete
  79. The Dropbox change is a royal pain in the arse. Grab the whole thing here:

    https://www.dropbox.com/sh/kav9ywqfbuknci1/AACBP_QORDGRs35y6Lhq2jXra?dl=0

    ReplyDelete
  80. Thanks David, really appreciate it. Do you know if changing the password will change user password for both kerberos and ldap user account in this setup? I am not sure, if user will have separate password for Kerberos principal and LDAP user account.

    ReplyDelete
    Replies
    1. Hey no problem, I hope you find what you need in these files.

      As for the password, the users in this setup have a Kerberos and an LDAP password. I have not worked on nor tried to have them use a single password for both systems. If you manage to configure this, please let me know!

      David

      Delete

Note: Only a member of this blog may post a comment.