Archive for the ‘ password ’ Category

Assigning a Custom Password policy to a subTree

Posted in directory, Directory Services, directory-server, ForgeRock, ldap, opendj, password, policy, security on June 20th, 2012 by Ludo – Comments Off

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.


Filed under: Directory Services Tagged: directory, directory-server, ForgeRock, ldap, opendj, password, policy, security

More secure passwords !

Posted in authentication, directory, Directory Services, ForgeRock, java, ldap, opendj, opensource, password, performance, security on June 13th, 2012 by Ludo – Comments Off

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.


Filed under: Directory Services Tagged: authentication, directory, ForgeRock, java, ldap, opendj, opensource, password, performance, security

Proper way of changing password in OpenAM

Posted in clientsdk, IdSvcs, password, REST on June 14th, 2010 by aldaris – Comments Off

There is always a point, when an OpenAM user ends up asking the question: ‘but how can my users change their passwords?’. The answer is quite tricky: there are several ways to do this, but you’re going to have problems with almost each one of them. But first things first, let’s see what do we want exactly:

Show an own form for the user, where he/she can give the old password, new password / confirmation of the new password combo and press the button, which changes the password with help of OpenAM. Change the users password in LDAP without enabling the force-reset password LDAP control. (Note this is only important if you use LDAP datastore, JDBC datastore is in early access stage, this article will not cover that).

This second point is not mandatory, but this feature is used often (by the LDAP module for example).
Note: your Directory Server configuration should contain a force-change-on-reset option with true value. The force-change-on-reset mode means, that if the password was resetted by an LDAP administrator, then the user HAS TO change his/her password to be able to do anything.
Note 2: if your DS uses this option, and you’re using the Datastore module (so something that’s not based on the LDAP module), then your module will genuinely fail, if you’re not handling this special case.

So what’s the proper way?

The proper way is when you have the old password, you validate it (by doing a BIND request) to make sure, that the user is who he tell he is. If the BIND was successful, then we execute a MODIFY command in the name of the just logged in user to modify the userPassword field. This is the proper way, because with this logic you are not resetting your password with the help of an administrator, so the force-reset stays false.

The REST API way

The REST API does not have a specific changepassword function, but it does have an update function as I mentioned in my earlier post. This also means, that because you don’t supply the old password, you just can’t reset the password as yourself, it has to run in the LDAP admins name, so this is a force-reset always! So the magic here is that you call the following REST function:

https:///openam/identity/update?identity_name=aldaris& identity_realm=/&identity_attribute_names=userPassword& identity_attribute_values_userPassword=newPass Doing this as the logged in user

If you do have the users sessionid, then you could call this resource as the user, IF your DS does not forbid modifying the userPassword for example with an ACI. OpenDS by default has the following global-aci:

(targetattr="audio||authPassword||description||displayName||givenName|| homePhone||homePostalAddress||initials||jpegPhoto||labeledURI||mobile|| pager||postalAddress||postalCode||preferredLanguage||telephoneNumber|| userPassword")(version 3.0; acl "Self entry modification"; allow (write) userdn="ldap:///self";)

This will enable you to modify your own password.

Doing this as admin

Since you’re doing this as admin, the password will be certainly overwritten.

The WebService way

The WebService way and the REST API way does not differ from each other, since they are both using the exact same code.

The ClientSDK way

The ClientSDK has several way accessing an Identity, for example using AMIdentityRepository:

SSOToken token = //getting an SSOToken object AMIdentityRepository idRepo = new AMIdentityRepository(token, "/realm"); IdSearchResults results = idRepo.searchIdentities(IdType.USER, "aldaris", new IdSearchControl()); Set identities = results.getSearchResults(); AMIdentity identity = (AMIdentity) identities.iterator().next(); Using AMIdentity#store

The idea here is to use the setAttributes method to update the desirable attributes and then call the store, something like this:

AMIdentity identity = ... Map attrs = new HashMap(); Set values = new HashSet(1); values.add(newPass); attrs.put("userPassword", values); identity.setAttributes(attrs); identity.store();

The problem with AMIdentity#store is the same as with the update function: you don’t supply the old password for the function, so there is no way, that this could end up without a force-reset. Also this solution worked for me with an IdRepo created with user token.

Using AMIdentity#changePassword

The AMIdentity class also has a changePassword method, which does exactly what we want, so let’s see some code:

AMIdentity identity = ... identity.changePassword(oldPass, newPass);

but I had one problem with this: when I accessed the AMIdentity from an IdRepo with a usertoken, then I had the following error message:

Permission to perform the read operation denied to id=aldaris,ou=user,dc=opensso,dc=java,dc=net

For me this does not make any sense, since I’m giving the old password and the new one, the username is supplied by the AMIdentity itself, then why do I need read permission and for what?? Anyway, when I did this with admintoken, then everything was working great without force-reset.

The OpenAM console way

There is also a way to change your password with help of OpenAM console. Just point your browser to

https:///openam/user/UMChangeUserPassword

I tried it many times, but the Old password field was always disabled for me, so this password change method also sets the force-reset bit…

Summary

As you can see there are many ways to change a users password, but the best way I think is to use ClientSDK with AMIdentity#changePassword or LDAP API directly. For testing the pwdReset flag I’ve used the following command:

ldapsearch -D "cn=Directory Manager" -b "ou=forgerock,o=org" -h localhost -p 1389 -w password "uid=aldaris" "pwdReset"

If you don’t need the force-change-on-reset functionality, then probably you can disable it in your Directory Server. If you want to hack, then maybe you can try out to delete the pwdReset attribute with the REST API, maybe it will work, I haven’t tried it.