inejge / ldap3

A pure-Rust LDAP library using the Tokio stack
Apache License 2.0
226 stars 39 forks source link

Password or ldaps issue #35

Closed CMMR2 closed 5 years ago

CMMR2 commented 5 years ago

I'm having problems with setting passwords for Active Directory users and its either an issue with the encoding of the password, which seems unlikely given the conversation on issue #20 or it is an issue with getting a secure connection.

I'm able to bind and create users, modify them, and everything else, its just the password problem holding me up. The result code is 53 - unwilling to perform. I'm binding with simple_bind and setting set_no_tls_verify to true in the connection settings.

I've used other ldap libraries in javascript and Go and disabling the security works in those apps but doesn't seem to work in this library. But again, because of the ambiguous nature of ldap result codes, I'm not sure what exactly the problem is.

Is there an example I've overlooked that shows how to set up a ldaps connection and setting a user password?

inejge commented 5 years ago

I don't have direct experience with changing AD passwords via LDAP, I just know it's a bit finicky. One blog post I've found lists the requirements, which you could check against the protocol trace, if you can get one.

CMMR2 commented 5 years ago

Thanks for the response.

I'm 99% sure the issue I'm having is an encoding one but I'm not nearly familiar enough with Rust to say for sure. I know that AD needs the password to be UTF-16le and that the first and last characters must be quotation marks.

I just can't seem to figure out how to send the password in that format.

inejge commented 5 years ago

There is an old SO question about converting strings to UTF-16. The answer is updated for the post-1.0 world and should still be valid. Try the 'Rust 1.0+' code (with the encoding crate), but use just the let mut v... line, which will give you a Vec<u8>, directly usable for LDAP Modify.

CMMR2 commented 5 years ago

I appreciate your continued help!

I tried the solution in that question earlier today but it doesn't work. I try using it like this:

conn.modify(&dn, vec![Mod::Replace("unicodePwd", hashset! {password})])

and when I run it, the compiler says at the hashset! {password} part:

expected &str, found struct std::vec::Vec

image

inejge commented 5 years ago

Ah, I see. Try

.modify(&dn, vec![Mod::Replace("unicodePwd".as_bytes(), hashset! { password.as_ref() })])

The type S in Mod's variants is used both for the attribute name and the value, which is fine for the usual &str/String case, but in this case the compiler sees "unicodePwd", which is a &str, and expects password to be the same, which it can't be. The trick is then to coerce both to the lowest common denominator, &[u8].

CMMR2 commented 5 years ago

That works perfectly! I can't tell you how grateful I am for your help. Thank you!

yocally commented 1 year ago

Hey sorry to comment on such an old issue, but I want to leave this for anyone in the future. On the AD server in my environment I had to first wrap the password in quotes before converting it to the byte array. Everything else in this issue was helpful though, so thank you to both of you for working this out before me.

inejge commented 1 year ago

On the AD server in my environment I had to first wrap the password in quotes before converting it to the byte array.

The blog post I've referenced in my first reply does have this step in the list of requirements. Quoting:

  • The new password must be enclosed in quotation marks, and it must use a UTF-16 little-endian encoding.