Monday, January 31, 2011

Setting Passwords in Microsoft Active Directory

The project that I am currently working on is starting in a different way than any other Identity Center (or Identity Management!) project that I have ever worked on. Rather than starting with AD/LDAP provisioning, role management or synchronization, they are starting with password management.
Usually I’m not a fan of this but there were a few reasons that this worked. First off, their authoritative source is SAP HCM, which is a relatively new implementation, so we know that the identity data is good and clean (They actually did a cleansing project when moving the data from their old legacy system). Also password management is a key need for the organization that will go far in proving the value and effectiveness of SAP NetWeaver Identity Management.

I have to admit that I went into this project with a lot of confidence. I’ve been successful in password management Proofs of Concept and done some work with the Password Hook that is a part of the SAP IDM offering. However as I’ve seen many a time there’s a world of difference between a PoC and a productive system.

What could the difference possibly be, you wonder? Well a lot of PoC systems have IdM and AD on the same host. Not so in production. This brought up a number of differences and changes that I needed to make the basic change AD password task that comes with NW IDM.
One of the things I’ve noticed in several Password Management projects with NW IDM is that even though the JAVA engine is preferred for most operations, that never works where Microsoft Active Directory is concerned.  In this case, the Windows engine is still superior.
Here is the code I developed

' Main function: pwdnext

Function pwdnext(Par)
HOST = ugetconstant("rep.LDAP_HOST")
LOGIN = ugetconstant("rep.LDAP_LOGIN")
PORT = ugetconstant("rep.LDAP_PORT")
strPassword = ugetconstant("rep.LDAP_PASSWORD")

RD= par("RD")
PWD = par("PWD")
strPath="LDAP://" & HOST &  "/" & RD

strUsername = LOGIN
Set adsNamespaceLDAP = GetObject("LDAP:")
Set adsMyObject = adsNamespaceLDAP.OpenDSObject (strPath,strUsername,strPassword,200)

strPath="LDAP://" & HOST &  "/" & RD
'Find user
Set adsUser = GetObject(StrPath)
'Set initial password
adsUser.SetPassword PWD
'Set flag to NOT force user to change the password on first login
adsUser.Put "pwdLastSet", -1

End Function

Since I didn’t mention it before, this script works with a TO GENERIC pass type.  Always the best when you need to bring in lots of information from the target screen.  This code is also pretty much the “bare essentials” and lacks support for handling encrypted passwords, validation logic, etc. The big changes I needed to make to the script from the original were the inclusion of the adsMyObject which allowed for a bind to Active Directory.  This code also exists in the pwdopen script, but it seems that the bind does not carry over.

The other very important thing that needs to happen is that the dispatcher service setup must also be properly configured. It is essential that the service be running with credentials that can make Active Directory changes. The following screenshot provides an example.
Dispatcher Service Log On Configuration

One of the key benefits of this approach is that there is no need for SSL to be setup between the IDM server and the Domain Controller.  A working SSL configuration is still required, however, when setting passwords in SAP's UME.

I hope this post has helped you out with understanding how password management can be achieved in SAP NetWeaver Identity Management 7.1, SP5. This example should work for any NW IDM 7.x implementation.

No comments: