A pure-Rust LDAP library using the Tokio stack.
The library can be used either synchronously or asynchronously. The aim is to offer essentially the same call interface for both flavors, with the necessary differences in interaction and return values according to the nature of I/O.
Version 0.6 has changed the signatures of low-level connection functions to
accomodate a single struct parameter which stores various connection options.
As part of this makeover, the LdapConnBuilder
struct was removed and
LdapConnSettings
added. Consult the current changelog and crate documentation
for detauls.
First, add this to your Cargo.toml
:
[dependencies.ldap3]
version = "0.6"
Next, add this to your crate root (src/lib.rs
or src/main.rs
):
extern crate ldap3;
The following two examples perform exactly the same operation and should produce identical
results. They should be run against the example server in the data
subdirectory of the crate source.
Other sample programs expecting the same server setup can be found in the examples
subdirectory.
extern crate ldap3;
use std::error::Error;
use ldap3::{LdapConn, Scope, SearchEntry};
fn main() {
match do_search() {
Ok(_) => (),
Err(e) => println!("{}", e),
}
}
fn do_search() -> Result<(), Box<Error>> {
let ldap = LdapConn::new("ldap://localhost:2389")?;
let (rs, _res) = ldap.search(
"ou=Places,dc=example,dc=org",
Scope::Subtree,
"(&(objectClass=locality)(l=ma*))",
vec!["l"]
)?.success()?;
for entry in rs {
println!("{:?}", SearchEntry::construct(entry));
}
Ok(())
}
extern crate futures;
extern crate ldap3;
extern crate tokio_core;
use std::error::Error;
use futures::Future;
use ldap3::{LdapConnAsync, Scope, SearchEntry};
use tokio_core::reactor::Core;
fn main() {
match do_search() {
Ok(_) => (),
Err(e) => println!("{}", e),
}
}
fn do_search() -> Result<(), Box<Error>> {
let mut core = Core::new()?;
let handle = core.handle();
let ldap = LdapConnAsync::new("ldap://localhost:2389", &handle)?;
let srch = ldap.and_then(|ldap|
ldap.search(
"ou=Places,dc=example,dc=org",
Scope::Subtree,
"(&(objectClass=locality)(l=ma*))",
vec!["l"]
))
.and_then(|response| response.success())
.and_then(|(rs, _res)| Ok(rs));
let rs = core.run(srch)?;
for entry in rs {
println!("{:?}", SearchEntry::construct(entry));
}
Ok(())
}
All LDAP protocol operations are implemented, as well as the support for request and response controls. Automatic paged results are supported, but referral chasing still isn't.
TLS support exists both for the case of immediate negotiation (aka ldaps://) and StartTLS. On Unix-like systems, connecting through a Unix domain socket with the ldapi:// scheme is supported.
Caveats:
-
It may be impossible to completely turn off certificate and hostname checking for TLS connections. There is support for relaxing hostname checking and passing a custom
TlsConnector
when establishing a connection, but the specifics depend on the amount of customization available when creating aTlsConnector
, which in turn depends on the platform TLS backend. -
Due to the structuring of support libraries, certificate errors may manifest themselves as a generic "broken pipe" error, and get triggered on first use of a connection, not on opening. To debug these kinds of issues, it's helpful to run the program while setting
RUST_LOG=tokio=trace
in the environment. See this issue for an example. -
Hostname resolution is synchronous by default. The resolver is configurable in the connection settings, so it's possible to plug in an async resolver running on the same event loop as the LDAP connection. The library still doesn't initiate any connections by itself, so setting a custom resolver shouldn't be necessary in most scenarios.
-
Unbind doesn't close our side of the connection, since the underlying TCP stream is inaccessible in the present implementation.
-
Abandon can only terminate currently active streaming searches.
-
Only version 3 of LDAP is supported.
-
CLDAP (LDAP over UDP) is not supported.
The ability of a streaming Search to deal with the Sync protocol (RFC 4533) will be developed in the 0.6 series. A similar mechanism may be usable for robust referral handling.
Licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE), or
- MIT license (LICENSE-MIT)
at your option.