I have tried to create virtual views of existing local data and I have realized that the rewrite/remap overlay (slapo-rwm) in conjunction with the relay backend (slapd-relay) (both are experimental) does not exactly do what I would like to have.
To explain the problem, let me consider the following hypothetical situation. We have two groups of UNIX clients. All clients should be accessed by the same set of users having different user ID on each client group. In addition, it would be nice to have different user passwords for each client group.
In the local schema, we define two new attributes xxxUidNumber and xxxUserPassword, and a new object class xxxPosixAccount holding them. The local.schema file, the initial slapd.conf file (OpenLDAP 2.4.22), and the real data ldif file are at the end of this email. The real data are in 'ou=users,ou=auth,o=example', and the virtual view is in 'ou=xxxUsers,ou=auth,o=example'.
1 The search problem ====================
Here are some queries and results to demonstrate it:
Real data: ----------
Search request A ~~~~~~~~~~~~~~~~ /usr/local/bin/ldapsearch -LLL -H ldaps://censor.ethz.ch -x \ -D "cn=ldap_manager,ou=auth,o=example" \ -w qwerty \ -b 'cn=user10,ou=users,ou=auth,o=example' dn: cn=user10,ou=users,ou=auth,o=example objectClass: top objectClass: person objectClass: posixAccount objectClass: xxxPosixAccount cn: user10 sn: user10 uid: user10 uidNumber: 1111 xxxUidNumber: 2222 gidNumber: 3333 homeDirectory: /tmp loginShell: /bin/tcsh gecos: User 10 userPassword:: e1NTSEF9QWlmMWtyQXhkRGQ3bHJ5amp6VzFoTUgxOFdVU01BPT0= xxxUserPassword: {SSHA}BaPK4xvEKVpYwj3qK0zbOWpVOAwSMA==
Virtual view: -------------
Search request B ~~~~~~~~~~~~~~~~ /usr/local/bin/ldapsearch -LLL -H ldaps://censor.ethz.ch -x \ -D "cn=ldap_manager,ou=auth,o=example" \ -w qwerty \ -b 'cn=user10,ou=xxxUsers,ou=auth,o=example' dn: cn=user10,ou=xxxUsers,ou=auth,o=example objectClass: top objectClass: person objectClass: posixAccount objectClass: xxxPosixAccount cn: user10 sn: user10 uid: user10 uidNumber: 1111 uidNumber: 2222 gidNumber: 3333 homeDirectory: /tmp loginShell: /bin/tcsh gecos: User 10 userPassword:: e1NTSEF9QWlmMWtyQXhkRGQ3bHJ5amp6VzFoTUgxOFdVU01BPT0= userPassword:: e1NTSEF9QmFQSzR4dkVLVnBZd2ozcUswemJPV3BWT0F3U01BPT0=
The rewrite/remap part in slapd.conf was as follows:
overlay rwm rwm-suffixmassage "ou=users,ou=auth,o=example" rwm-map attribute userPassword xxxUserPassword rwm-map attribute uidNumber xxxUidNumber
Because of the simple mapping, the reply contains uidNumber and userPassword attributes two times. To eliminate this, we modify the rewrite/remap part in slapd.conf:
overlay rwm rwm-suffixmassage "ou=users,ou=auth,o=example" rwm-map attribute userPassword xxxUserPassword rwm-map attribute userPassword rwm-map attribute uidNumber xxxUidNumber rwm-map attribute uidNumber
Now the answer from the previous search request (B) seems to be as desired:
dn: cn=user10,ou=xxxUsers,ou=auth,o=example objectClass: top objectClass: person objectClass: posixAccount objectClass: xxxPosixAccount cn: user10 sn: user10 uid: user10 uidNumber: 2222 gidNumber: 3333 homeDirectory: /tmp loginShell: /bin/tcsh gecos: User 10 userPassword:: e1NTSEF9QmFQSzR4dkVLVnBZd2ozcUswemJPV3BWT0F3U01BPT0=
But the next search request returns values, although one would expect an empty result set, as the attribute xxxUidNumber (used in the filter) is not explicitly present in the virtual view (it is mapped):
Search request C ~~~~~~~~~~~~~~~~ /usr/local/bin/ldapsearch -LLL -H ldaps://censor.ethz.ch -x \ -D "cn=ldap_manager,ou=auth,o=example" \ -w qwerty \ -b 'ou=xxxUsers,ou=auth,o=example' \ '(xxxUidNumber=*)' dn: cn=user10,ou=xxxUsers,ou=auth,o=example objectClass: top objectClass: person objectClass: posixAccount objectClass: xxxPosixAccount cn: user10 sn: user10 uid: user10 uidNumber: 2222 gidNumber: 3333 homeDirectory: /tmp loginShell: /bin/tcsh gecos: User 10 userPassword:: e1NTSEF9QmFQSzR4dkVLVnBZd2ozcUswemJPV3BWT0F3U01BPT0=
I think the attribute xxxUidNumber should be removed from the internal query to the foreign data set, because it is used as a foreign name (and in the same time not as a local name) in the mapping, and the query (C) above should return an empty result set.
One can improve this by modifying the rewrite/remap part in slapd.conf as follows:
overlay rwm rwm-suffixmassage "ou=users,ou=auth,o=example" rwm-map attribute cn * rwm-map attribute sn * rwm-map attribute uid * rwm-map attribute gidNumber * rwm-map attribute homeDirectory * rwm-map attribute loginShell * rwm-map attribute gecos * rwm-map attribute userPassword xxxUserPassword rwm-map attribute uidNumber xxxUidNumber rwm-map attribute *
Now both search requests (B and C) work as expected. The last remap line correctly removes everything what is not mapped. The problem here is that one has to explicitly list all desired attributes in the remap configuration. If a new attribute is added to the real data, it would not show in the result set without a change in the remap configuration.
2 The authentication problem ============================
The following two bind request use the same password for authentication, regardless of the mapping and the value of the attribute xxxUserPassword.
/usr/local/bin/ldapsearch -LLL -H ldaps://censor.ethz.ch -x \ -D "cn=user10,ou=users,ou=auth,o=example" \ -w abc123 \ -b 'cn=user10,ou=users,ou=auth,o=example' dn dn: cn=user10,ou=users,ou=auth,o=example
/usr/local/bin/ldapsearch -LLL -H ldaps://censor.ethz.ch -x \ -D "cn=user10,ou=xxxUsers,ou=auth,o=example" \ -w abc123 \ -b 'cn=user10,ou=xxxUsers,ou=auth,o=example' dn dn: cn=user10,ou=xxxUsers,ou=auth,o=example
If we use the userPassword (xyz789), reported by the view (e.g. query B), the bind request returns 'Invalid credentials'.
If I understand it correctly, this is not a bug. The LDAP bind request does not contain the name of the attribute holding the user password at the server site, so there is (unfortunately) nothing to map.
There are many real life situations where, for security reasons, it would be desirable to have different passwords for different applications, or groups of applications/clients (e.g. web access, UNIX login, etc.). Unfortunately, it seems the present virtual views (slapo-rwm + slapd-relay) cannot solve it. For the moment, I see only one possibility -- to create a copy of the user entries and to modify the userPassword attribute. (Please let me know, if you know a better solution.) But there are disadvantages connected with this approach, for example the maintenance of the data consistency, large indices, etc.
My question is -- would it be possible to solve the password mapping in the OpenLDAP software? For example, (i) to extend the structure holding the bind request data to include an attribute name, (ii) to initialise its value to 'userPassword', (iii) to allow slapo-rwm to rewrite/remap it, and then (iv) to use the new value of the attribute name for the internal user password verification.
With best regards,
Vlado
-------------------------------------------------------------------------
local.schema: ============= attributetype ( 1.3.6.1.4.1.9999.2.1.102 NAME 'xxxUidNumber' DESC 'An integer uniquely identifying a user in an administrative domain (XXX private)' EQUALITY integerMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
attributetype ( 1.3.6.1.4.1.9999.2.1.105 NAME 'xxxUserPassword' DESC 'RFC2256/2307: password of user (XXX private)' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{128} )
objectclass ( 1.3.6.1.4.1.9999.2.2.10 NAME 'xxxPosixAccount' DESC 'Abstraction of an account with POSIX attributes (XXX private)' SUP top AUXILIARY MAY ( xxxUidNumber $ xxxUserPassword ) )
slapd.conf: =========== include /usr/local/openldap/etc/openldap/schema/core.schema include /usr/local/openldap/etc/openldap/schema/cosine.schema include /usr/local/openldap/etc/openldap/schema/nis.schema include /etc/openldap/local.schema
pidfile /var/openldap/slapd.pid argsfile /var/openldap/slapd.args
loglevel 256
TLSCertificateFile /etc/openldap/xxx_cert.pem TLSCertificateKeyFile /etc/openldap/xxx_key.pem TLSRandFile /var/run/prngd-socket
TLSCACertificateFile /etc/openldap/yyy_cacert.pem
database relay suffix "ou=xxxUsers,ou=auth,o=example" subordinate
overlay rwm rwm-suffixmassage "ou=users,ou=auth,o=example" rwm-map attribute userPassword xxxUserPassword rwm-map attribute uidNumber xxxUidNumber
database hdb suffix "ou=auth,o=example" directory /var/openldap/hdb
rootdn "cn=ldap_manager,ou=auth,o=example" rootpw {SSHA}jN4XaG5UmYFwpY/47aW0nLralRwSMA==
dbconfig set_cachesize 0 268435456 0
dbconfig set_flags DB_TXN_NOSYNC dbconfig set_flags DB_LOG_AUTOREMOVE
dbconfig set_lk_max_locks 3000 dbconfig set_lk_max_lockers 3000 dbconfig set_lk_max_objects 3000
dbconfig set_lg_regionmax 1048576 dbconfig set_lg_max 10485760 dbconfig set_lg_bsize 2097152 dbconfig set_lg_dir /var/log/hdb
dbconfig set_tmp_dir /tmp
Real data: ========== dn: ou=auth,o=example objectClass: top objectClass: organizationalUnit ou: auth
dn: ou=users,ou=auth,o=example objectClass: top objectClass: organizationalUnit ou: users
dn: cn=user10,ou=users,ou=auth,o=example objectClass: top objectClass: person objectClass: posixAccount objectClass: xxxPosixAccount cn: user10 sn: user10 uid: user10 uidNumber: 1111 xxxUidNumber: 2222 gidNumber: 3333 homeDirectory: /tmp loginShell: /bin/tcsh gecos: User 10 # abc123 userPassword: {SSHA}Aif1krAxdDd7lryjjzW1hMH18WUSMA== # xyz789 xxxUserPassword: {SSHA}BaPK4xvEKVpYwj3qK0zbOWpVOAwSMA==
openldap-technical@openldap.org