A visit to the new Oslo offices

Entrance of ForgeRock Oslo officeI’m just leaving Oslo after a short visit to our new Oslo offices and meetings with my colleagues from Sales and Business Development.

It was nice finally meeting with many of the ForgeRock employees I’ve been working with through Skype, phone and email. And also meeting with some visitors from other ForgeRock locations. Working in Oslo office feels very similar than working in the Grenoble ones : there is a friendly and relaxed atmosphere, although with a deep concentration and intense work going on.

I’ll be coming back to Oslo on a more regular pace starting from September, but as I’m leaving, I wish I could come back with my whole family during the summer time, as it’s probably the best season to come to Norway : the light is incredible, the weather great and it feels so relaxing. Hmmm, this sounds like a plan for family vacation for next year !?

Assigning a Custom Password policy to a subTree

OpenDJ supports defining password policies that are quite complete in term of security measures to reduce the risks associated with textual passwords. It also defines 2 default policies, one for the administrators such as “cn=Directory Manager”, and one for all other users : the “Default Password Policy”. But it is possible to define additional password policies and assign them to individual users or group of users. Today, we are considering how to assign a password policy to all users under a specific subtree. In the article below, I first define a new custom password policy and then I demonstrate 2 ways of assigning that password policy to all persons under the ou=people,dc=example,dc=com subtree.

Defining a custom password policy using dsconfig:

$ dsconfig create-password-policy \
 --set default-password-storage-scheme:Salted\ SHA-256 \
 --set password-attribute:userpassword \
 --type generic \
 --policy-name Custom\ PP \
 --hostname lpmac.local \
 --port 4444 \
 --bindDN cn=Directory\ Manager \
 --bindPassword ****** \
 -X -n

1- Assigning the password policy through a Virtual Attribute.

$ dsconfig create-virtual-attribute \
 --set attribute-type:ds-pwp-password-policy-dn \
 --set enabled:true \
 --set value:cn=Custom\ PP,cn=Password\ Policies,cn=config \
 --set base-dn:ou=people,dc=example,dc=com \
 --set filter:\(objectClass=person\) \
 --type user-defined \
 --name Custom\ PP\ Assignment \
 --hostname lpmac.local \
 --port 4444 \
 --bindDN cn=Directory\ Manager \
 --bindPassword ****** \
 -X -n

Check that the password policy is assigned properly:

$ ldapsearch -D "cn=directory manager" -w secret12 -p 1389 -b "" 'uid=user.1' '+' userPassword
dn: uid=user.1,ou=People,dc=example,dc=com
userPassword: {SSHA}u+52Ld6iaTvFoNlQvqTHrn1BBW9IjjT2/I25hg==
numSubordinates: 0
ds-pwp-password-policy-dn: cn=Custom PP,cn=Password Policies,cn=config
structuralObjectClass: inetOrgPerson
pwdPolicySubentry: cn=Custom PP,cn=Password Policies,cn=config
subschemaSubentry: cn=schema
hasSubordinates: false
entryDN: uid=user.1,ou=people,dc=example,dc=com
entryUUID: 4e9b7847-edcb-3791-b11b-7505f4a55af4

Change the user password, the new password should be encoded with the scheme specified (SSHA-256)

$ ldappasswordmodify -p 1389 -D uid=user.1,ou=People,dc=example,dc=com -w password -A -n newPassword
 The LDAP password modify operation was successful

$ ldapsearch -D "cn=directory manager" -w secret12 -p 1389 -b "" 'uid=user.1' userPassword
dn: uid=user.1,ou=People,dc=example,dc=com
userPassword: {SSHA256}vjIdZEtF1AIiM0EgY9unZUXXublwQwlOCoe4RYEIHtpzumW1hYyvNg==

2 – Assigning the password policy using Collective Attributes :

$ ldapmodify -D cn=directory\ manager -w secret12 -p 1389
dn: cn=Pwp for Users,dc=example,dc=com
changetype: add
objectclass: collectiveAttributeSubEntry
objectclass: extensibleObject
objectclass: subentry
objectclass: top
ds-pwp-password-policy-dn;collective: cn=Custom PP,cn=Password Policies,cn=config
subtreeSpecification: { base "ou=people", specificationFilter "(objectclass=person)"}

Processing ADD request for cn=Pwp for Users,dc=example,dc=com
ADD operation successful for DN cn=Pwp for Users,dc=example,dc=com

Now we can check that the password policy is well assigned, and that it’s used when changing password for example.

$ ldapsearch -D "cn=directory manager" -w secret12 -p 1389 -b "" 'uid=user.1' '+' userPassword
dn: uid=user.1,ou=People,dc=example,dc=com
userPassword: {SSHA}6tHBLHh2C25UpAsKX0eq0d6LEXYGX+Jcm4dh7g==
numSubordinates: 0
ds-pwp-password-policy-dn: cn=Custom PP,cn=Password Policies,cn=config
structuralObjectClass: inetOrgPerson
etag: 000000008211ac6a
pwdPolicySubentry: cn=Custom PP,cn=Password Policies,cn=config
subschemaSubentry: cn=schema
hasSubordinates: false
collectiveAttributeSubentries: cn=Pwp for Users,dc=example,dc=com
entryDN: uid=user.1,ou=people,dc=example,dc=com
entryUUID: 4e9b7847-edcb-3791-b11b-7505f4a55af4

$ ldappasswordmodify -p 1389 -D uid=user.1,ou=People,dc=example,dc=com -w password -A -n newPassword
 The LDAP password modify operation was successful

$ ldapsearch -D "cn=directory manager" -w secret12 -p 1389 -b "" 'uid=user.1' userPassword
 dn: uid=user.1,ou=People,dc=example,dc=com
 userPassword: {SSHA256}WswyH9ANoKcxQWlSn/eL8h/dNk532K/e5zGlJcwiwMLsCQqw+cAX0Q==

So which method to assign a password policy to specific users is best ?

The first method should be preferred when the password policy is defined in the configuration (as we’ve done in the example). Both configuration entries, the password policy and its assignment, are under the “cn=config” tree,  but need to be defined in all replicas.

The second method defines the assignment of a policy to users as an subentry collocated with the data, and will be replicated. It should be preferred if the password policy is also defined as a subEntry, along with its assignment. Such way of configuring a password policy is documented in the Administration Guide, Configuring Password Policies section, procedure 10.3 – To Create a Subentry Based Password Policy.

More secure passwords !

I’ve received an intriguing request from a customer last week :  he wanted to know if we’ve done benchmarks of the password hashing schemes that are available in OpenDJ, our LDAP directory service. Their fear was that with stronger schemes, they could not sustain a high authentication rate.

In light of the LinkedIn leak of several millions of passwords, hashed with a simple unsalted SHA1, I decided to run a quick and simple test.

SSHA1 is the default hashing scheme for password in OpenDJ. The salt is an 8 bytes (64-bit) random string and is used with the password to produce the 20 bytes message digest. But OpenDJ directory server supports a wide range of password hashing scheme and salted SHA512 is currently the most secure hashing algorithm we support (and the salt here is also an 8 bytes (64-bit) random octet string).

So for the test, I generated a sample directory data set with 10 000 users, and imported it in the OpenDJ directory (a 2.5 development build) with the default settings, on my laptop (MacBook Pro, 2.2 GHz intel Core i7).

$ ldapsearch -D "cn=directory manager" -w secret12 -p 1389 -b "dc=example,dc=com" 'uid=user.10' dn userPassword
dn: uid=user.10,ou=People,dc=example,dc=com
userPassword: {SSHA}cchzM+LrPCvbZdthOC8e62d4h7a4CfoNvl6d/w==

I then ran an “authrate” which is a small benchmark tool that allows to stress an LDAP server with a high number of authentications (LDAP Bind requests) and let it run to 5 minutes.

authrate -h localhost -p 1389 -g 'rand(0,10000)' -D "uid=user.%d,ou=people,dc=example,dc=com" -w password -c 32 -f
-----------------------------------------------------------------
 Throughput     Response Time
 (ops/second)   (milliseconds)
 recent average recent average 99.9% 99.99% 99.999% err/sec
 -----------------------------------------------------------------
 ...
 26558.0  26148.9   1.179    1.195  10.168  19.431  156.421      0.0

I then stopped the server, changed the import default password encryption scheme to Salted SHA512, and reimported the data.

$ ldapsearch -D "cn=directory manager" -w secret12 -p 1389 -b "dc=example,dc=com" 'uid=user.10' dn userPassword
 dn: uid=user.10,ou=People,dc=example,dc=com
 userPassword: {SSHA512}eTGiwtTM4niUKNkEBy/9t03UdbsyYTL1ZXhy6uFnw4X0T6Y9Zf5/dS7hDIdx3/UTlUQ/9JjNV9fOg2BkmVgBhWWu5WpWKPog

And then re-run the “authrate”

$ authrate -h localhost -p 1389 -g 'rand(0,10000)' -D "uid=user.,ou=people,dc=example,dc=com" -w password -c 32 -f
 -----------------------------------------------------------------
 Throughput     Response Time
 (ops/second)   (milliseconds)
 recent average recent average 99.9% 99.99% 99.999% err/sec
 -----------------------------------------------------------------
 ...
 25481.7 25377.6 1.222 1.227 10.470 15.473 158.234 0.0

As you can see, there is not much of a difference in throughput or response time, when using the strongest algorithm to hash user password. So do not hesitate to change the default settings and make use of the strongest password hashing schemes with OpenDJ. It could save you from the embarrassment of, one day, contacting each of your users or customers to ask them to change their compromised password.

The default password hashing schemes are in 2 locations :

  • The default password policy for all passwords that are changed online.
dn: cn=Default Password Policy,cn=Password Policies,cn=config
ds-cfg-default-password-storage-scheme: cn=Salted SHA-512,cn=Password Storage Schemes,cn=config
  • In the Import Password Policy
dn: cn=Password Policy Import,cn=Plugins,cn=config
ds-cfg-default-user-password-storage-scheme: cn=Salted SHA-512,cn=Password Storage Schemes,cn=config

Both properties can be changed with dsconfig while the OpenDJ server is running, and the new scheme will be used for all subsequent operations.

We’ve moved office !

As we’re growing the team in the Grenoble area, we’ve finally moved office to the “Silvaco” building in the Montbonnot tech area.

ForgeRock France new office building

We now have enough space for the whole team, interns and for the coming new hires (and yes, we still have positions opened). The facilities include a small cafeteria, some showers for the cyclers, soccer players or runners, and a well air-conditioned machine room that we haven’t fully taken advantage yet. Here are a few photos:

ForgeRock France office buildingInside office
ForgeRock France Office meeting room

We’re still in the progress of decorating the office, adding a more relaxed and friendly atmosphere, with certainly some “Rock attitude”.

If you’re in the neighborhood or you plan to pay us a visit, here’s the google map to come:


Don’t hesitate to drop by, we have coffee and may be more, especially if you are a developer with a passion for code and Java.

Finally, I’d like to have a special thank Mancala Networks and its CEO Marc Rozier for having hosting us for the last year, as we were building the team.