Here’s my set up and the design decisions I’ve made so far. Since this code is not yet submitted for code review, there is a good chance that it will change prior to deployment.
Users will be stored in a flat collection. ou=Users,$SUBTREE and be based on the standard LDAP objectClass inetOrgPerson which is defined in /etc/openldap/schema/inetorgperson.ldif. Currently, only two fields are used: cn and sn. cn is used for the bind call, and is the id field in the user object.
Tenants are in a collection that is a peer to Users. Tenants are instancs of the groupOfNames object class defined in /etc/openldap/schema/core.ldif. Tenant membership is indicated by the presence of the User’s DN in the tenant’s members attribute.
Roles are instances of the LDAP object class organizationalRole defined in /etc/openldap/schema/core.ldif. Role assignment is indicated by the presence of the User’s DN in the roleOccupant attribute.
Configuration of LDAP for the Keystone server is provided by the [LDAP] stanza in the appropriate keystone.conf file. Here are the supported values
url
user
password
suffix
use_dumb_member
user_tree_dn
tenant_tree_dn
role_tree_dn
And an example of what my config file looks like:
01 [ldap]
02 url = ldap://localhost
03 tree_dn = dc=younglogic,dc=com
04 user_tree_dn = dc=Users,dc=younglogic,dc=com
05 role_tree_dn = dc=Roles,dc=younglogic,dc=com
06 tenant_tree_dn = dc=Groups,dc=younglogic,dc=com
07 user = dc=Manager,dc=younglogic,dc=com
08 password = freeipa4all
09 backend_entities = ['Tenant', 'User', 'UserRoleAssociation', 'Role']
10 suffix =cn=younglogic,cn=com
11
12 [identity]
13 driver = keystone.identity.backends.ldap.Identity
Not all of these fields need to be specified. It is expected that the user will supply simply the suffix field, and not override the values of user_tree_dn,role_tree_dn, or tenant_tree_dn.
backend_entities is not currently honored. It is expected that LDAP will instead either manage all of these or non e of them, with token management handled by a different backend provider.
use_dumb_member is still honored from the previous incarnation, but has not been tested, nor do I understand the intention of this code.
The unit tests for the LDAP code use a common code sournce with the other Identity management backends. To run just the LDAP unit tests, from the Keystone directory, run
1 python ./run_tests.py test_backend_ldap
Additionally, the unit tests can be run against a live OpenLDAP server by running.
1 python ./run_tests.py _ldap_livetest
All tests pass successfully on my development machine as of this posting.
I’m running Fedora 16, which supports OpenLDAP. Specifically I am running openldap-servers-2.4.26-5.fc16.x86_64. To start the service, run
1 sudo service slapd start
To configure the server, I use a file I call manager.ldif:
01 dn: olcDatabase={2}hdb,cn=config
02 changetype: modify
03 replace: olcSuffix
04 olcSuffix: dc=younglogic,dc=com
05 -
06 replace: olcRootDN
07 olcRootDN: dc=Manager,dc=younglogic,dc=com
08 -
09 add: olcRootPW
10 olcRootPW: {SSHA}lBDIdfwvZkITal0k9tdhiCUolxpf6anu
You should modify the suffix for your organization.
Execute the configuration with:
1 sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f ./manager.ldif
And test that you can now do a simple bind to the localhost server.
1 ldapsearch -x -D "dc=Manager,dc=younglogic,dc=com" -H ldap://localhost -w freeipa4all -b ou=Groups,dc=younglogic,dc=com "(objectClass=*)"
Now set up the subtree for Keystone. I use file I call org.ldif
01 dn: dc=younglogic,dc=com
02 dc: younglogic
03 objectClass: dcObject
04 objectClass: organizationalUnit
05 ou: younglogic
06
07 dn: ou=Groups,dc=younglogic,dc=com
08 objectClass: top
09 objectClass: organizationalUnit
10 ou: groups
11
12 dn: ou=Users,dc=younglogic,dc=com
13 objectClass: top
14 objectClass: organizationalUnit
15 ou: users
16
17 dn: ou=Roles,dc=younglogic,dc=com
18 objectClass: top
19 objectClass: organizationalUnit
20 ou: users
Technically, the Roles ou is not required. My original though was that this collection would contain the superset of roles possible for all of the Tenants. However, I have not implemented that.
Current code is commited to Github I will update this link when the code is ready for review.
Here’s my set up and the design decisions I’ve made so far. Since this code is not yet submitted for code review, there is a good chance that it will change prior to deployment.
Users will be stored in a flat collection. ou=Users,$SUBTREE and be based on the standard LDAP objectClass inetOrgPerson which is defined in /etc/openldap/ schema/ inetorgperson. ldif. Currently, only two fields are used: cn and sn. cn is used for the bind call, and is the id field in the user object.
Tenants are in a collection that is a peer to Users. Tenants are instancs of the groupOfNames object class defined in /etc/openldap/ schema/ core.ldif. Tenant membership is indicated by the presence of the User’s DN in the tenant’s members attribute.
Roles are instances of the LDAP object class organizationalRole defined in /etc/openldap/ schema/ core.ldif. Role assignment is indicated by the presence of the User’s DN in the roleOccupant attribute.
Configuration of LDAP for the Keystone server is provided by the [LDAP] stanza in the appropriate keystone.conf file. Here are the supported values
url
user
password
suffix
use_dumb_member
user_tree_dn
tenant_tree_dn
role_tree_dn
And an example of what my config file looks like: dc=com dc=younglogic, dc=com dc=younglogic, dc=com dc=younglogic, dc=com dc=younglogic, dc=com ation', 'Role'] cn=com identity. backends. ldap.Identity
01 [ldap]
02 url = ldap://localhost
03 tree_dn = dc=younglogic,
04 user_tree_dn = dc=Users,
05 role_tree_dn = dc=Roles,
06 tenant_tree_dn = dc=Groups,
07 user = dc=Manager,
08 password = freeipa4all
09 backend_entities = ['Tenant', 'User', 'UserRoleAssoci
10 suffix =cn=younglogic,
11
12 [identity]
13 driver = keystone.
Not all of these fields need to be specified. It is expected that the user will supply simply the suffix field, and not override the values of user_tree_ dn,role_ tree_dn, or tenant_tree_dn.
backend_entities is not currently honored. It is expected that LDAP will instead either manage all of these or non e of them, with token management handled by a different backend provider.
use_dumb_member is still honored from the previous incarnation, but has not been tested, nor do I understand the intention of this code.
The unit tests for the LDAP code use a common code sournce with the other Identity management backends. To run just the LDAP unit tests, from the Keystone directory, run
1 python ./run_tests.py test_backend_ldap
Additionally, the unit tests can be run against a live OpenLDAP server by running.
1 python ./run_tests.py _ldap_livetest
All tests pass successfully on my development machine as of this posting.
I’m running Fedora 16, which supports OpenLDAP. Specifically I am running openldap- servers- 2.4.26- 5.fc16. x86_64. To start the service, run
1 sudo service slapd start
To configure the server, I use a file I call manager.ldif: {2}hdb, cn=config dc=com dc=younglogic, dc=com kITal0k9tdhiCUo lxpf6anu
01 dn: olcDatabase=
02 changetype: modify
03 replace: olcSuffix
04 olcSuffix: dc=younglogic,
05 -
06 replace: olcRootDN
07 olcRootDN: dc=Manager,
08 -
09 add: olcRootPW
10 olcRootPW: {SSHA}lBDIdfwvZ
You should modify the suffix for your organization.
Execute the configuration with:
1 sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f ./manager.ldif
And test that you can now do a simple bind to the localhost server. dc=younglogic, dc=com" -H ldap://localhost -w freeipa4all -b ou=Groups, dc=younglogic, dc=com "(objectClass=*)"
1 ldapsearch -x -D "dc=Manager,
Now set up the subtree for Keystone. I use file I call org.ldif dc=com dc=younglogic, dc=com dc=younglogic, dc=com dc=younglogic, dc=com
01 dn: dc=younglogic,
02 dc: younglogic
03 objectClass: dcObject
04 objectClass: organizationalUnit
05 ou: younglogic
06
07 dn: ou=Groups,
08 objectClass: top
09 objectClass: organizationalUnit
10 ou: groups
11
12 dn: ou=Users,
13 objectClass: top
14 objectClass: organizationalUnit
15 ou: users
16
17 dn: ou=Roles,
18 objectClass: top
19 objectClass: organizationalUnit
20 ou: users
Technically, the Roles ou is not required. My original though was that this collection would contain the superset of roles possible for all of the Tenants. However, I have not implemented that.
Current code is commited to Github I will update this link when the code is ready for review.