Thursday, June 21, 2012

LINQ to LDAP: How do passwords work?

A couple hours of trial and error I have finally figured out setting passwords in Active Directory and Lightweight Directory Services. As a result of this I ported all of the dynamic functionality to some extension methods for LdapConnection.

Modifying passwords has been in the back of my head ever since the question was asked here. If I had looked closer at the answer on StackOverflow I would have seen that the solution was for Sun-One. If there's one thing I've learned working on LINQ to LDAP it's that every server has been implemented a little differently.

So let's get down to it. The first thing I learned is userPassword in AD LDS is not the "real" password attribute. That would be unicodePwd. I then received a very helpful "An operation error occurred." A few searches later and I found out that means you'll have to use port 636 instead of 389. Turns out Microsoft does not allow changing the password over a non SSL connection. However, you don't have to explicitly set SSL to true if you're post Windows 2000 (I hope you are). Okie dokie let's fire this up.

"The LDAP server is unavailable."

You'll get this error if SSL is not on for your server. This lead me to generating a self signed certificate and installing it for my local instance. You can read about the how and why here. Alright, now my server is responding to requests on 636, but I'm getting "A value in the request is invalid." That's when I found this post explaining how to do this the right way. I wish I had found that first. So here's the resulting code:

For those using AD LDS and you don't have SSL on, let me save you some trouble. I found this post later allowing you to enable modifying the password over port 389. Well I hope this was helpful.

I should probably add that you should not enable setting passwords over an unencrypted connection. I am working in a test environment so it's no big deal for me.