2012. augusztus 31., péntek

Kerberos with LDAP Backend on Ubuntu 12.04 - Part Five

In the previous four posts we added the Kerberos-schema to our OpenLDAP-server, did the initial Kerberos setup and created the first principals, connected PAM and MIT-Kerberos first on the server then on a client. Today we set up the smbkrb5pwd overlay.
(Ez a cikk magyarul is olvasható.)
We need this overlay for two things:
  • we do not intend to create a separate Kerberos-principal for every new user by hand
  • and we do want the Kerberos-password synced with the LDAP-password.
We have used the overlay before to sync the userPassword attribute (the LDAP password) with the sambaNTPassword attribute containing the Samba password.

Today we are going to do something similar but today we sync the userPassword attribute with the krbPrincipalKey attribute. It is important to state that although I use the two synchronizations  parallel it is possible to set up and use the module without Samba too.

Somewhere (I cannot find where) I have read that the belongings of Kerberos are not to be stored directly under the LDAP root if one intents to use this overlay. That's why I set up the Kerberos container to reside in cn=krbcontainer,dc=itthon,dc=cucc .

Last time we have already downloaded, compiled and installed the smbkrb5pwd overlay. We only do a configuration change to make the overlay handle not only the Samba but the Kerberos password too. The overlay does the following: Upon an LDAP password change
  • if a Kerberos principal for the user already exists then the principal key is changed 
  • if there is no principal it is created
If you did not start using the overlay then your first job is to compile and do the loading  (smbkrb5pwd_load.ldif). A smbkrb5pwd_setup.ldif will change a bit as you can exclude the line olcSmbKrb5PwdMustChange (the documentationsays only the samba part pays attention to it) and the line with olcSmbKrb5PwdEnable instead of samba yopu put krb5 . And you are supposed to put in a line like olcSmbKrb5PwdKrb5Realm: ITTHON.CUCC too.

If your overlay already handles samba - like on my test system -  then your first job is to look up its number in the configuration:
sudo ldapsearch -Y EXTERNAL -b cn=config
And now being clever you write the file smbkrb5pwd_kerberos_enable.ldiff (as you can se in my case the muber of the overlay is 0):
dn: olcOverlay={0}smbkrb5pwd,olcDatabase={1}hdb,cn=config
changetype: modify
replace: olcSmbKrb5PwdEnable
olcSmbKrb5PwdEnable: samba
olcSmbKrb5PwdEnable: krb5
-
add: olcSmbKrb5PwdKrb5Realm
olcSmbKrb5PwdKrb5Realm: ITTHON.CUCC
Then run the command:
sudo ldapmodify -Y EXTERNAL -f smbkrb5pwd_kerberos_enable.ldiff

Eithtre way you have followed the point is that when finished the ldapsearch should give something like this (again you only need to see samba if you intend to use the overlay for samba too) :
# {0}smbkrb5pwd, {1}hdb, config
dn: olcOverlay={0}smbkrb5pwd,olcDatabase={1}hdb,cn=config
objectClass: olcOverlayConfig
objectClass: olcSmbKrb5PwdConfig
olcOverlay: {0}smbkrb5pwd
olcSmbKrb5PwdMustChange: 2592000
olcSmbKrb5PwdRequiredClass: posixAccount
olcSmbKrb5PwdEnable: samba
olcSmbKrb5PwdEnable: krb5
olcSmbKrb5PwdKrb5Realm: ITTHON.CUCC

If you now issu the following command the we will not be able to connect as kerberos does not know yet that smbkrb5pwd is allowed to change passwords.
ldappasswd -D cn=admin,dc=itthon,dc=cucc -w secret -s newpassword uid=jdoe,ou=People,dc=itthon,dc=cucc
Result: Connect error (-11)
In the syslog you will find something like this:
smbkrb5pwd conn=1021 op=1 : kadm5_init_with_skey() failed for user bela: Invalid argument

Let's do something about it. First we have to make sure that the command
hostname -f
issued on the server reurns the FQDN (Fully Qualified Domain Name) of the system - in my case ubuserver.itthon.cucc. (Without the full stop at the end of course.)
That achieved we need to create a principal for the smbkrb5pwd then export the keys in the file the overlay will look for them. Mind the name of the principal, you have to use the server's FQDN. Bold with yellow background is written by us. You will see that four keys are exported.
sudo kadmin.local 
Password: 
Authenticating as principal root/admin@ITTHON.CUCC with password.
kadmin.local:  addprinc -randkey smbkrb5pwd/ubuserver.itthon.cucc@ITTHON.CUCC
WARNING: no policy specified for smbkrb5pwd/ubuserver.itthon.cucc@ITTHON.CUCC; defaulting to no policy
Principal "smbkrb5pwd/ubuserver.itthon.cucc@ITTHON.CUCC" created.
kadmin.local:  ktadd -k /etc/ldap/slapd.d/openldap-krb5.keytab smbkrb5pwd/ubuserver.itthon.cucc@ITTHON.CUCC
Entry for principal smbkrb5pwd/ubuserver.itthon.cucc@ITTHON.CUCC with kvno 2, encryption type aes256-cts-hmac-sha1-96 added to keytab WRFILE:/etc/ldap/slapd.d/openldap-krb5.keytab.
Entry for principal smbkrb5pwd/ubuserver.itthon.cucc@ITTHON.CUCC with kvno 2, encryption type arcfour-hmac added to keytab WRFILE:/etc/ldap/slapd.d/openldap-krb5.keytab.
Entry for principal smbkrb5pwd/ubuserver.itthon.cucc@ITTHON.CUCC with kvno 2, encryption type des3-cbc-sha1 added to keytab WRFILE:/etc/ldap/slapd.d/openldap-krb5.keytab.
Entry for principal smbkrb5pwd/ubuserver.itthon.cucc@ITTHON.CUCC with kvno 2, encryption type des-cbc-crc added to keytab WRFILE:/etc/ldap/slapd.d/openldap-krb5.keytab. 
kadmin.local:  quit
You have to make sure that the openldap user has the right to read this file and others have not:
sudo chown openldap:openldap /etc/ldap/slapd.d/openldap-krb5.keytab
You need to give the rights for this new principal so it can create users (a) and can change passwords. The file /etc/krb5kdc/kadm5.acl has to look more or less like this:
*/admin *
smbkrb5pwd/ubuserver.itthon.cucc ac
And of coure the new privileges require a restart:
sudo service krb5-admin-server restart
I have already mentioned that kadmind is brought to conciusness very slowly. If you have a user you know it has to work with, try again and again:
kadmin -p kerbadmin/admin
When ready the:
sudo kadmin -p smbkrb5pwd/ubuserver.itthon.cucc -k -t /etc/ldap/slapd.d/openldap-krb5.keytab
It has to work. If it does not then you got an issue to sort out.

And now something I've played (khmm...) for hours. At the beginning they are present in the LDAP-database:
ldapsearch -x -D cn=admin,dc=itthon,dc=cucc -w secret -LLL -b ou=People,dc=itthon,dc=cucc dn
dn: ou=People,dc=itthon,dc=cucc

dn: uid=bela,ou=People,dc=itthon,dc=cucc

dn: uid=root,ou=People,dc=itthon,dc=cucc

dn: uid=nobody,ou=People,dc=itthon,dc=cucc

dn: uid=suser1,ou=People,dc=itthon,dc=cucc
And those are the ones having Kerberos-principals:
kadmin -p kerbadmin/admin
Authenticating as principal kerbadmin/admin with password.
Password for kerbadmin/admin@ITTHON.CUCC: 
kadmin:  listprincs
jdoe@ITTHON.CUCC
K/M@ITTHON.CUCC
krbtgt/ITTHON.CUCC@ITTHON.CUCC
kadmin/admin@ITTHON.CUCC
kadmin/changepw@ITTHON.CUCC
kadmin/history@ITTHON.CUCC
kadmin/ubuserver.itthon.cucc@ITTHON.CUCC
kerbadmin/admin@ITTHON.CUCC
smbkrb5pwd/ubuserver.itthon.cucc@ITTHON.CUCC
May I underline that jdoe is the only one of the real users who already has a principal and he happens to have one as in the third part of this series I have created one for him. The Kerberos-attributes of jdoe in the LDAP-database are stored under the jdoe dn - check it out on your system:
ldapsearch -x -D cn=admin,dc=itthon,dc=cucc -w secret -LLL -b uid=jdoe,ou=People,dc=itthon,dc=cucc
And you can see that the krbcontainer we have created to hold the Kerberos data has no idea about John:
ldapsearch -x -D cn=admin,dc=itthon,dc=cucc -w secret -LLL -b cn=ITTHON.CUCC,cn=krbcontainer,dc=itthon,dc=cucc dn
dn: cn=ITTHON.CUCC,cn=krbcontainer,dc=itthon,dc=cucc

dn: krbPrincipalName=K/M@ITTHON.CUCC,cn=ITTHON.CUCC,cn=krbcontainer,dc=itthon,
 dc=cucc

dn: krbPrincipalName=krbtgt/ITTHON.CUCC@ITTHON.CUCC,cn=ITTHON.CUCC,cn=krbconta
 iner,dc=itthon,dc=cucc

dn: krbPrincipalName=kadmin/admin@ITTHON.CUCC,cn=ITTHON.CUCC,cn=krbcontainer,d
 c=itthon,dc=cucc

dn: krbPrincipalName=kadmin/changepw@ITTHON.CUCC,cn=ITTHON.CUCC,cn=krbcontaine
 r,dc=itthon,dc=cucc

dn: krbPrincipalName=kadmin/history@ITTHON.CUCC,cn=ITTHON.CUCC,cn=krbcontainer
 ,dc=itthon,dc=cucc

dn: krbPrincipalName=kadmin/ubuserver.itthon.cucc@ITTHON.CUCC,cn=ITTHON.CUCC,c
 n=krbcontainer,dc=itthon,dc=cucc

dn: krbPrincipalName=kerbadmin/admin@ITTHON.CUCC,cn=ITTHON.CUCC,cn=krbcontaine
 r,dc=itthon,dc=cucc

dn: krbPrincipalName=smbkrb5pwd/ubuserver.itthon.cucc@ITTHON.CUCC,cn=ITTHON.CU
 CC,cn=krbcontainer,dc=itthon,dc=cucc
That is the reason why you have no success running the command
ldappasswd -D cn=admin,dc=itthon,dc=cucc -w secret -s newpassword uid=jdoe,ou=People,dc=itthon,dc=cucc
.

But if you happen to use suser1 (someone else already added to LDAP but having no Kerberos-principal) for the passowrd setting experiment, you will be happier. Issuing the command
ldappasswd -D cn=admin,dc=itthon,dc=cucc -w secret -s newpassword uid=suser1,ou=People,dc=itthon,dc=cucc
then it works like a charm. Open syslog syslog and you'll see that smbkrb5pwd is creating the principal and sets the passwords. A check:
kadmin -p kerbadmin/admin
Authenticating as principal kerbadmin/admin with password.
Password for kerbadmin/admin@ITTHON.CUCC: 
kadmin:  listprincs
bela@ITTHON.CUCC
K/M@ITTHON.CUCC
krbtgt/ITTHON.CUCC@ITTHON.CUCC
kadmin/admin@ITTHON.CUCC
kadmin/changepw@ITTHON.CUCC
kadmin/history@ITTHON.CUCC
kadmin/ubuserver.itthon.cucc@ITTHON.CUCC
kerbadmin/admin@ITTHON.CUCC
smbkrb5pwd/ubuserver.itthon.cucc@ITTHON.CUCC
suser1@ITTHON.CUCC
Wow, suser1 has a principal. In the right place:
ldapsearch -x -D cn=admin,dc=itthon,dc=cucc -w secret -LLL -b cn=ITTHON.CUCC,cn=krbcontainer,dc=itthon,dc=cucc dn
dn: cn=ITTHON.CUCC,cn=krbcontainer,dc=itthon,dc=cucc

dn: krbPrincipalName=K/M@ITTHON.CUCC,cn=ITTHON.CUCC,cn=krbcontainer,dc=itthon,
 dc=cucc

dn: krbPrincipalName=krbtgt/ITTHON.CUCC@ITTHON.CUCC,cn=ITTHON.CUCC,cn=krbconta
 iner,dc=itthon,dc=cucc

dn: krbPrincipalName=kadmin/admin@ITTHON.CUCC,cn=ITTHON.CUCC,cn=krbcontainer,d
 c=itthon,dc=cucc

dn: krbPrincipalName=kadmin/changepw@ITTHON.CUCC,cn=ITTHON.CUCC,cn=krbcontaine
 r,dc=itthon,dc=cucc

dn: krbPrincipalName=kadmin/history@ITTHON.CUCC,cn=ITTHON.CUCC,cn=krbcontainer
 ,dc=itthon,dc=cucc

dn: krbPrincipalName=kadmin/ubuserver.itthon.cucc@ITTHON.CUCC,cn=ITTHON.CUCC,c
 n=krbcontainer,dc=itthon,dc=cucc

dn: krbPrincipalName=kerbadmin/admin@ITTHON.CUCC,cn=ITTHON.CUCC,cn=krbcontaine
 r,dc=itthon,dc=cucc

dn: krbPrincipalName=smbkrb5pwd/ubuserver.itthon.cucc@ITTHON.CUCC,cn=ITTHON.CU
 CC,cn=krbcontainer,dc=itthon,dc=cucc

dn: krbPrincipalName=suser1@ITTHON.CUCC,cn=ITTHON.CUCC,cn=krbcontainer,dc=itth
 on,dc=cucc
And the Kerberos-attributes are not stored under the suser1 entry:
ldapsearch -x -D cn=admin,dc=itthon,dc=cucc -w secret -LLL -b uid=suser1,ou=People,dc=itthon,dc=cucc
Instead you will find them here:
ldapsearch -x -D cn=admin,dc=itthon,dc=cucc -w titok -LLL -b krbPrincipalName=suser1@ITTHON.CUCC,cn=ITTHON.CUCC,cn=krbcontainer,dc=itthon,dc=cucc

This way it works. You only have to promise that you will not create the principals by hand.

So let us think. This is what we've alreay done:
  • If one changes a password in LDAP directly updating the userPassword attribute then the overlay smbkrb5pwd will not know about it and will propagate the change neighter to Samba nor to Kerberos.
  • If one changes a password in LDAP using exop then smbkrb5pwd will be noticed and will propagate it both to Samba and Kerberos (what is more it even creates the Keberos principal).
  • If one changes her passowrd in Windows then Samba store is using exop and because of the setting ldap passwd sync = only  it updates only the Unix password.
  • And the exop causes smbkrb5pwd tho change both the Samba and Kerberos password.
  • But if the Kerberos password changes we will never ever find that out and therefore it will not be propagated to anywhere.
  • This means that at this point when someone changes her password on a Linux client (this means the Kerberos password) noone will know about it.
What is the solution?
Very easy. On a Linux-system usig PAM you can use different systems for athentication and password change. Athentication is handled by the file /etc/pam.d/common-auth which at this point on my client system looks like this (comments excluded):
auth    [success=3 default=ignore]    pam_krb5.so minimum_uid=1000
auth    [success=2 default=ignore]    pam_unix.so nullok_secure try_first_pass
auth    [success=1 default=ignore]    pam_ldap.so use_first_pass
auth    requisite            pam_deny.so
auth    required            pam_permit.so
It means that the authentication process tries Kerberos at first and when no success then the local user table is lookedn up and ath the end LDAP is tried. As in the last ten minutes Kerberos and LDAP passwords are the same an LDAP user is supposed to get in with the first try.
When changing passwords the power is given to the file /etc/pam.d/common-password . At this point (comments excluded) it looks like this:
password    [success=3 default=ignore]    pam_krb5.so minimum_uid=1000
password    [success=2 default=ignore]    pam_unix.so obscure use_authtok try_first_pass sha512
password    [success=1 user_unknown=ignore default=die]    pam_ldap.so try_first_pass
password    requisite            pam_deny.so
password    required            pam_permit.so
(From the line of LDAP we'have removed the entry use_authok a long time ago.)
If you comment out the Kerberos line and issue the passwd command with an already logged in user you will immediately see the the Linux client tres to change the LDAP password. And that is exactly we want! You only have to make sure that the LDAP password change uses exop and for that we have already cared for editing the file /etc/ldap.conf .

So the magic works - the Kerberos-LDAP-Samba password synchronisation is done.

Further reading:
http://www.opinsys.fi/en/smbkrb5pwd-password-syncing-for-openldap-mit-kerberos-and-samba

Nincsenek megjegyzések: