Search code examples
c#asp.net-coreactive-directoryldapopenldap

C# LDAP user change password failed. Is SSL connection must?


I am writing an ASP.NET Core 5 Web API (platform independent) to change the LDAP user password. I'm using the library Novell.Directory.Ldap.

This is my code:

var ldapHost = "192/168.*.*";
var loginDN = "CN=something,DC=something";   //loginDn of the user itself or admin 
var opassword = "Abcd@11111111";  //oldpassword
var npassword = "Xyzw@22222222";  //newpassword
npassword =  '"' + npassword + '"';

LdapConnection conn = new LdapConnection();

Console.WriteLine("Connecting to:" + ldapHost);

conn.Connect(ldapHost, LdapConnection.DefaultPort);
conn.Bind(loginDN, opassword);

LdapModification[] modifications = new LdapModification[2];
LdapAttribute deletePassword = new LdapAttribute("userPassword", opassword);
modifications[0] = new LdapModification(LdapModification.Delete, deletePassword);

LdapAttribute addPassword = new LdapAttribute("userPassword", npassword);
modifications[1] = new LdapModification(LdapModification.Add, addPassword);

conn.Modify(loginDN, modifications);

I am testing this code for a Windows AD domain as well as Linux OpenLDAP. Both LDAP server's users have the attribute property userPassword present.

When I run this code LdapModification.ADD throws an error that No such attribute userPassword. when I try to find the solution I get people using attribute unicodePwd, but it needs an SSL connection.

Is the SSL connection a must for AD domains and Open LDAP? Or how else to solve the above error? Please help.


Solution

  • While AD has a userPassword attribute, it's just a pointer to the unicodePwd attribute, which is the real password attribute. But userPassword doesn't always work, as described in the documentation. For Active Directory, you're better off using unicodePwd directly.

    The documentation for unicodePwd says that you require either SSL or SASL encryption to set the attribute. SASL would usually be done with Kerberos. If you were using DirectoryEntry, that's easily done by specifying AuthenticationTypes.Sealing. With Novell.Directory.Ldap, I don't know if that's possible, and this open issue suggests that it isn't (yet).

    Unless you're willing to switch to using Sytem.DirectoryServices (which, in .NET Core, would lock you into running your app on Windows only), then I think you are stuck requiring SSL.

    The unicodePwd attribute also requires a very specific format. The documentation says:

    the DC requires that the password value be specified in a UTF-16 encoded Unicode string containing the password surrounded by quotation marks, which has been BER-encoded as an octet string per the Object(Replica-Link) syntax.

    In C#, that's easily done like this:

    Encoding.Unicode.GetBytes("\"NewPassword\"")