Export Crowd users and groups to ldap

I need to migrate users and groups created in Atlassian Crowd to OpenDJ, an open source LDAP server written in Java fork of OpenDS; in this way Crowd will act just as SSO and it will rely on OpenDJ to store users.

Crowd can rely on several LDAP servers but it doesn’t have tools to export users and groups to ldap so I created a couple of queries (my database is PostgreSQL) to export in ldif files:

COPY(select 'dn: cn=' || user_name || ',ou=users,dc=my,dc=website,dc=com' || chr(10) ||
'objectClass: inetOrgPerson' || chr(10) ||
'objectClass: organizationalPerson' || chr(10) ||
'objectClass: person' || chr(10) ||
'objectClass: top' || chr(10) ||
'mail: ' || lower_email_address || chr(10) ||
'uid: ' || user_name || chr(10) ||
'cn: ' || user_name || chr(10) ||
'givenName: ' || first_name || chr(10) ||
'sn: ' || last_name || chr(10) ||
'displayName: ' || display_name || chr(10) ||
'userPassword: ' || credential || chr(10) || chr(10)
from cwd_user) TO '/tmp/users.ldif';

Of course you can customize the query to adapt to your needs, have in mind that the userPassword most probably is stored in PKCS5S2 format (you can see that the passwords extracted start with {PKCS5S2} prefix, see Crowd hashes), which is the default for Crowd or called Atlassian-security. In this sense only ApacheDS currently (2.0.0-m16) supports the same format while for OpenDJ there is a change to be done to the pbkdf2 storage scheme. It is up to you if you prefer to reset passwords or try to keep them during the migration.

As small parenthesis I have been asking to those people of Crowd about their connector for ApacheDS, since their connector supports ApacheDS 1.5.x (not anymore maintained by ApacheDS developers) and they are not sure to spend time in updating such connector for version 2.0, see my question on Atlassian Answers. An interesting thing to know is that also WSO2 Identity Server has bundled ApacheDS 1.5.7, you can see it also in the source code but you can connect it to OpenDJ.

In case your Crowd was setup with SSHA1, you can also use Openldap, see FAQ.

For the groups the query would be something like:

COPY(select 'dn: cn=' || parent_name || 'BASE_GROUPS' || chr(10) ||
'cn: ' || parent_name || chr(10) ||
'objectClass: groupOfUniqueNames' || chr(10) ||
'objectClass: top' || chr(10) ||
'uniquemember:' array_to_string(array_agg(child_name),',')
from cwd_membership group by parent_name) TO '/tmp/groups.ldif';

As you can see I used the functions array_to_string and array_agg integrated in PostgreSQL to create the list of users. These users will not have their base (,ou=users,dc=my,dc=website,dc=com), so, after executing the query, you can apply some regular expression (I used Notepad++) to replace the regex “([,])” with “,ou=users,dc=my,dc=website,dc=com\nuniquemember: cn” which replaces all the “,” inserted with the query with their base. At the end, I replaced BASE_GROUPS with “,ou=groups,dc=my,dc=website,dc=com“.

You can import the ldif files with PHPLdapAdmin or directly in OpenDJ with import-ldif command, keep in mind that you need to allow pre encoded passwords before importing.

Enjoy the migration !





16 reasons to choose OpenDJ

For a client I needed to put in place an LDAP system to be connected with Atlassian Crowd (SSO), after doing a comparison with OpenLDAP (C), Apache DS (Java) and OpenDJ (Java) I decided to go for OpenDJ for several reasons:

  1. It is open source released with CDDL 1.0 license; while Apache DS is released with Apache license and OpenLDAP with it is own license.
  2. it has worldwide commercial support, some here in Belgium; Apache DS has only one company and OpenLDAP has also it is worldwide support
  3. It is a fork of OpenDS like Oracle Unified Directory so you can still find common problems for  both products
  4. The project has a clear roadmap, also described in the wiki, also ApacheDS has it.
  5. The ForgeRock company provides also another SSO solution (OpenAM), so in case in a future I want to change SSO I can think to use it, while Apache DS no.
  6. It comes packaged as ZIP, RPM and DEB, while ApacheDS has a package for each Operating System and OpenLDAP is packaged in many Operating Systems.
  7. It has very good documentation with a lot of examples (released in EPUB, HTML, PDF and RTF), while I found the one from ApacheDS  simpler or in progress (HTML , PDF) and the one of OpenLDAP is good (released in HTML and PDF).
  8. It has a rich command line tool, while I found the command line of ApacheDS simpler (relying mostly on the Apache Directory Studio or on ldap client).
  9. It is shipped with a java client (not web) while Apache DS has a gui based on Eclipse (Directory Studio)
  10. it has REST API on top of the ldap protocol, while ApacheDS leaves to SCIM such job; therefore I hope there will be a web interface using the REST API.
  11. It supports replication out of the box, also ApacheDS has itOpenLDAP as well.
  12. It seems to have very good performance (almost at OpenLDAP level) at least in comparison to ApacheDS.
  13. It has a support for the virtual attribute IsMemberOf, useful to check which groups a user belongs to, while for ApacheDS the feature needs to be still implemented.
  14. It has an implementation of the PKCS5S2 (see PBKDF2) which is used by Crowd as default despite the implementation is  different from Crowd and ApacheDS, which OpenLDAP doesn’t have (and some other password schemes as well)
  15. The development team uses Continuous Integration practices (by testing against Ubuntu and Windows), also ApacheDS by using the common Apache Jenkins and testing on Ubuntu.
  16. The team has coding guidelines providing checkstyle rules, also ApacheDS has some guidelines and OpenLDAP has few

To test the performances, I did an LDAP jmeter script and published on Github, just to say that OpenDJ has it is own tool, and Tsung can also test LDAP server.

I have been working with my brother to change the PBKDF2 implementation so it is almost similar to Crowd and ApacheDS differing for the printing format of the iterations.

Enjoy using OpenDJ !