Closed clux closed 7 years ago
Hmm, yes, the problem is that the decoder blindly tries to convert the binary value to a UTF-8 string and fails. It's difficult to solve without knowing the type of the attribute before decoding. As a workaround, you could retrieve just the attributes which you know are not binary. I'll think about the ways to make it work without making the user go through major contortions in order to retrieve values.
Meanwhile, could you paste the output of that last println!("entry {:?}", entry);
here? I'd like to see if AD provides any type hints.
Ah, yes, it does actually work when I specify only the sAMAccountName
in attrs rather than an empty vec.
I'm sending you an email with the output.
I have at any rate gotten my auth setup to work with AD now, and will try to move this function into my web server somehow. Relatively painless even with my limited understanding of this stuff. Leaving my final test code here:
extern crate ldap3;
use ldap3::{LdapConn, Scope, SearchEntry};
use std::process;
use std::env;
fn main() {
// You need to have set these first:
let user = env::var("DOMAIN_USER").unwrap();
let pass = env::var("DOMAIN_PASS").unwrap();
// Make an ldap connection:
let ldap = LdapConn::new("ldaps://myldaphost.com").unwrap();
// Bind with a read-only account (required to be allowed to search with our AD)
let (res, ctrls) = ldap.simple_bind("acc1", "pw1").expect("bind");
println!("got bind res {:?} with ctrls {:?}", res, ctrls);
// Search for your user:
let (result_set, result, _controls) = ldap.search(
"dc=some,dc=stuff,dc=com", // search base
Scope::Subtree,
&format!("sAMAccountName={}", user), // search filter
vec!["sAMAccountName"] // what we want returned
).expect("search");
// Find the `dn` entry of your user
println!("{:?}", result);
let entry = result_set.into_iter().next().expect("result first");
let se = SearchEntry::construct(entry);
println!("entry: {:?}", se);
// Try to bind to that `dn` entry with your password:
let (authres, ctrls2) = ldap.simple_bind(&se.dn, &pass).expect("bind");
println!("got authres {:?}, ctlrs {:?}", authres, ctrls2);
if authres.rc == 0 {
println!("authenticated");
process::exit(0);
}
else {
println!("failed to authenticate: {}", authres.text);
process::exit(1);
}
}
Thanks a lot for your help :)
NP, thank you for putting up with freshly-minted code. In that spirit, here's a tentative fix for binary values. Could you try it out?
[dependencies.ldap3]
git = "https://github.com/inejge/ldap3"
rev = "c0565a89ad2221d43ef213d69b03ef31fdfd7415"
NP!
Have checked and it is able to construct the SearchEntry
now even with an empty attr
vec, so looks good on my end :)
Seems the weird data in AD now appears wrapped in a double array inside bin_attrs on the return here, but those were never what I needed anyway. Excerpt from debug print:
bin_attrs: {"objectGUID": [[228, ..., 109]], "objectSid": [[1, ..., 0]]}
Yes, what you're seeing for each attribute is a Vec
of Vec<u8>
, with a single element (an attribute could have multiple values).
Thanks for the report and testing!
Hello again 😄 Some more adventures in AD land. Perhaps some more different parsing issues?
produces a crash in
SearchEntry::construct
I can replace the last print with a debug entry print:
println!("entry {:?}", entry);
and the executable runs to completion then. The debug data looks like a bunch of sensible AD binary data to me, but I don't know enough about AD to see what's going wrong here (if you would like to see it, I'm happy to send that information along).Any ideas?