Samba – smbk5pwd overlay on OpenLDAP 2.4

configurationopenldappassword-managementsamba

I have an OpenLDAP server and I want to configure the smbk5pwd overlay to make OpenLDAP update the sambaNTPassword and sambaLMPassword attributes automatically when a change occurs on userPassword. Versions:

slapd           2.4.23-7.3
slapd-smbk5pwd  2.4.23-7.3

module

dn: cn=module{1},cn=config
objectClass: olcModuleList
cn: module{1}
olcModuleLoad: smbk5pwd
olcModulePath: /usr/lib/ldap

Module is loaded without errors. The following happens if I try to add the overlay:

#!RESULT ERROR
#!CONNECTION ldap://192.168.10.145:389
#!DATE 2014-03-07T09:55:49.078
#!ERROR [LDAP: error code 80 - <olcSmbK5PwdEnable> handler exited with 1]
dn: olcOverlay=smbk5pwd,olcDatabase={1}hdb,cn=config
changetype: add
objectClass: olcSmbK5PwdConfig
objectClass: olcOverlayConfig
objectClass: olcConfig
objectClass: top
olcOverlay: smbk5pwd
olcSmbK5PwdEnable: samba

LDAP log:

smbk5pwd: unable to find "krb5KDCEntry" objectClass.
olcSmbK5PwdEnable: value #0: <olcSmbK5PwdEnable> handler exited with 1!

I've included the following schemas:

cn={0}core.ldif
cn={1}cosine.ldif
cn={2}nis.ldif
cn={3}inetorgperson.ldif
cn={4}mozillaorgperson.ldif
cn={5}evolutionperson.ldif
cn={6}qmailuser.ldif
cn={7}samba.ldif

What am I missing? Do I have to load another module or schema?

EDIT – found and included krb5-kdc.schema before samba.schema

It is here for those who also struggle finding it:

# $Id: krb5-kdc.schema,v 1.1 2004-03-22 17:25:05 quanah Exp $
# Definitions for a Kerberos V KDC schema

# OID Base is iso(1) org(3) dod(6) internet(1) private(4) enterprise(1) padl(5322) kdcSchema(10)
#
# Syntaxes are under 1.3.6.1.4.1.5322.10.0
# Attributes types are under 1.3.6.1.4.1.5322.10.1
# Object classes are under 1.3.6.1.4.1.5322.10.2

# Syntax definitions

#krb5KDCFlagsSyntax SYNTAX ::= {
#   WITH SYNTAX            INTEGER
#--        initial(0),             -- require as-req
#--        forwardable(1),         -- may issue forwardable
#--        proxiable(2),           -- may issue proxiable
#--        renewable(3),           -- may issue renewable
#--        postdate(4),            -- may issue postdatable
#--        server(5),              -- may be server
#--        client(6),              -- may be client
#--        invalid(7),             -- entry is invalid
#--        require-preauth(8),     -- must use preauth
#--        change-pw(9),           -- change password service
#--        require-hwauth(10),     -- must use hwauth
#--        ok-as-delegate(11),     -- as in TicketFlags
#--        user-to-user(12),       -- may use user-to-user auth
#--        immutable(13)           -- may not be deleted         
#   ID                     { 1.3.6.1.4.1.5322.10.0.1 }
#}

#krb5PrincipalNameSyntax SYNTAX ::= {
#   WITH SYNTAX            OCTET STRING
#-- String representations of distinguished names as per RFC1510
#   ID                     { 1.3.6.1.4.1.5322.10.0.2 }
#}

# Attribute type definitions

attributetype ( 1.3.6.1.4.1.5322.10.1.1
    NAME 'krb5PrincipalName'
    DESC 'The unparsed Kerberos principal name'
    EQUALITY caseExactIA5Match
    SINGLE-VALUE
    SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )

attributetype ( 1.3.6.1.4.1.5322.10.1.2
    NAME 'krb5KeyVersionNumber'
    EQUALITY integerMatch
    SINGLE-VALUE
    SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )

attributetype ( 1.3.6.1.4.1.5322.10.1.3
    NAME 'krb5MaxLife'
    EQUALITY integerMatch
    SINGLE-VALUE
    SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )

attributetype ( 1.3.6.1.4.1.5322.10.1.4
    NAME 'krb5MaxRenew'
    EQUALITY integerMatch
    SINGLE-VALUE
    SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )

attributetype ( 1.3.6.1.4.1.5322.10.1.5
    NAME 'krb5KDCFlags'
    EQUALITY integerMatch
    SINGLE-VALUE
    SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )

attributetype ( 1.3.6.1.4.1.5322.10.1.6
    NAME 'krb5EncryptionType'
    EQUALITY integerMatch
    SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 )

attributetype ( 1.3.6.1.4.1.5322.10.1.7
    NAME 'krb5ValidStart'
    EQUALITY generalizedTimeMatch
    ORDERING generalizedTimeOrderingMatch
    SYNTAX 1.3.6.1.4.1.1466.115.121.1.24
    SINGLE-VALUE )

attributetype ( 1.3.6.1.4.1.5322.10.1.8
    NAME 'krb5ValidEnd'
    EQUALITY generalizedTimeMatch
    ORDERING generalizedTimeOrderingMatch
    SYNTAX 1.3.6.1.4.1.1466.115.121.1.24
    SINGLE-VALUE )

attributetype ( 1.3.6.1.4.1.5322.10.1.9
    NAME 'krb5PasswordEnd'
    EQUALITY generalizedTimeMatch
    ORDERING generalizedTimeOrderingMatch
    SYNTAX 1.3.6.1.4.1.1466.115.121.1.24
    SINGLE-VALUE )

# this is temporary; keys will eventually
# be child entries or compound attributes.
attributetype ( 1.3.6.1.4.1.5322.10.1.10
    NAME 'krb5Key'
    DESC 'Encoded ASN1 Key as an octet string'
    SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 )

attributetype ( 1.3.6.1.4.1.5322.10.1.11
    NAME 'krb5PrincipalRealm'
    DESC 'Distinguished name of krb5Realm entry'
    SUP distinguishedName )

attributetype ( 1.3.6.1.4.1.5322.10.1.12
    NAME 'krb5RealmName'
    EQUALITY octetStringMatch
    SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{128} )

# Object class definitions

objectclass ( 1.3.6.1.4.1.5322.10.2.1
    NAME 'krb5Principal'
    SUP top
    AUXILIARY
    MUST ( krb5PrincipalName )
    MAY ( cn $ krb5PrincipalRealm ) )

objectclass ( 1.3.6.1.4.1.5322.10.2.2
    NAME 'krb5KDCEntry'
    SUP krb5Principal
    AUXILIARY
    MUST ( krb5KeyVersionNumber )
    MAY ( krb5ValidStart $ krb5ValidEnd $ krb5PasswordEnd $
          krb5MaxLife $ krb5MaxRenew $ krb5KDCFlags $
          krb5EncryptionType $ krb5Key ) )

objectclass ( 1.3.6.1.4.1.5322.10.2.3
    NAME 'krb5Realm'
    SUP top
    AUXILIARY
    MUST ( krb5RealmName ) )

slaptest ran successfully and I was able to add the overlay, however if I change userPassword, the other attributes are untouched. The userPassword attributes contain SHA1 hashes.

Best Answer

You must use the RFC 3062 Password Modify Extended Operation. See the README in the source distribution (there is no man page, AFAICT). You can do this from the command line with OpenLDAP's ldappasswd (which is different to slappasswd which just hashes password values in various ways).

userPassword has grown special semantics over time, none of which were intended (and which are not strictly compliant with the specifications). It's not uncommon for it to have "compare only" (authenticate only) access or no read access, and have client or server dependent transformation (e.g. client-side or server-side hashing of content). Password Modify is well defined and accepts only plaintext passwords, and can use an administrator defined hash method. This extension provides an abstraction layer for passwords (and also allows for password storage to be decoupled from the directory entirely). It's also needed for password complexity enforcement, that can't be done if clients are allowed to write pre-hashed valued directly to userPassword.

e.g. (perl): http://search.cpan.org/~gbarr/perl-ldap/lib/Net/LDAP/Extension/SetPassword.pm

You can confirm support by querying the Root DSE (dn ""), e.g.

$ ldapsearch -H ldaps://myldap/ [ -D user -w password ] \
 -s base -b "" "(objectclass=*)" supportedExtension 
[...]
dn:
supportedExtension: 1.3.6.1.4.1.1466.20037    # STARTTLS
supportedExtension: 1.3.6.1.4.1.4203.1.11.1   # password modify
supportedExtension: 1.3.6.1.4.1.4203.1.11.3   # who am i
supportedExtension: 1.3.6.1.1.8               # cancel request