ldap3/lib.rs
1//! A pure-Rust LDAP client library using the Tokio stack.
2//!
3//! ## Usage
4//!
5//! In `Cargo.toml`:
6//!
7//! ```toml
8//! [dependencies.ldap3]
9//! version = "0.12.1"
10//! ```
11//!
12//! ## Summary
13//!
14//! The library provides both synchronous and asynchronous interfaces. The [`LdapConn`](struct.LdapConn.html)
15//! structure is the starting point for all synchronous operations. [`LdapConnAsync`](struct.LdapConnAsync.html)
16//! is its asynchronous analogue, and [`Ldap`](struct.Ldap.html) is the low-level asynchronous handle used
17//! internally by `LdapConn`, and explicitly by the users of the asynchronous interface.
18//!
19//! In the [struct list](#structs), async-related structs have an asterisk (__*__) after
20//! the short description.
21//!
22//! The documentation is written for readers familiar with LDAP concepts and terminology,
23//! which it won't attempt to explain. If you need an introductory text, you can try the
24//! [primer](https://github.com/inejge/ldap3/blob/27a247c8a6e4e2c86f664f4280c4c6499f0e9fe5/LDAP-primer.md)
25//! included in this library.
26//!
27//! ## Compile-time features
28//!
29//! The following features are available at compile time:
30//!
31//! * __sync__ (enabled by default): Synchronous API support.
32//!
33//! * __gssapi__ (disabled by default): Kerberos/GSSAPI support. On Windows, system support
34//! crates and SDK libraries are used. Elsewhere, the feature needs Clang and its development
35//! libraries (for `bindgen`), as well as the Kerberos development libraries. On Debian/Ubuntu,
36//! that means `clang-N`, `libclang-N-dev` and `libkrb5-dev`. It should be clear from these
37//! requirements that GSSAPI support uses FFI to C libraries; you should consider the security
38//! implications of this fact.
39//!
40//! For usage notes and caveats, see the documentation for
41//! [`Ldap::sasl_gssapi_bind()`](struct.Ldap.html#method.sasl_gssapi_bind).
42//!
43//! * __ntlm__ (disabled by default): NTLM authentication support. Username and password must
44//! be provided, and the password must be in cleartext. It works on TLS connections, or clear
45//! connections with no signing or sealing. With TLS, a channel binding token is sent to the
46//! server if possible. See [`Ldap::sasl_ntlm_bind()`](struct.Ldap.html#method.sasl_ntlm_bind).
47//!
48//! * __tls__ (enabled by default): TLS support, backed by the `native-tls` crate, which uses
49//! a platform-specific TLS backend. This is an alias for __tls-native__.
50//!
51//! * __tls-rustls-...__ (disabled by default): TLS support, backed by the Rustls library. The
52//! bare __tls-rustls__ flag, used previously for this purpose, won't work by itself; one
53//! must choose the crypto provider for Rustls. There are two predefined flags for this
54//! purpose, __tls-rustls-aws-lc-rs__ and __tls-rustls-ring__. If another provider is
55//! needed, it can be chosen by activating the corresponding feature in Rustls and setting
56//! the flags __tls-rustls__ and __rustls-provider__. For example the AWS FIPS provider can
57//! be chosen with:
58//!
59//! ... `--features tls-rustls,rustls/fips,rustls-provider`
60//!
61//! Not selecting a provider, or selecting one without specifying __rustls-provider__, will
62//! produce a compile-time error.
63//!
64//! Without any features, only plain TCP connections (and Unix domain sockets on Unix-like
65//! platforms) are available. For TLS support, __tls__ and __tls-rustls__ are mutually
66//! exclusive: choosing both will produce a compile-time error.
67//!
68//! ## Examples
69//!
70//! The following two examples perform exactly the same operation and should produce identical
71//! results. They should be run against the example server in the `data` subdirectory of the crate source.
72//! Other sample programs expecting the same server setup can be found in the `examples` subdirectory.
73//!
74//! ### Synchronous search
75//!
76//! ```rust,no_run
77//! use ldap3::{LdapConn, Scope, SearchEntry};
78//! use ldap3::result::Result;
79//!
80//! fn main() -> Result<()> {
81//! let mut ldap = LdapConn::new("ldap://localhost:2389")?;
82//! let (rs, _res) = ldap.search(
83//! "ou=Places,dc=example,dc=org",
84//! Scope::Subtree,
85//! "(&(objectClass=locality)(l=ma*))",
86//! vec!["l"]
87//! )?.success()?;
88//! for entry in rs {
89//! println!("{:?}", SearchEntry::construct(entry));
90//! }
91//! Ok(ldap.unbind()?)
92//! }
93//! ```
94//!
95//! ### Asynchronous search
96//!
97//! ```rust,no_run
98//! use ldap3::{LdapConnAsync, Scope, SearchEntry};
99//! use ldap3::result::Result;
100//!
101//! #[tokio::main]
102//! async fn main() -> Result<()> {
103//! let (conn, mut ldap) = LdapConnAsync::new("ldap://localhost:2389").await?;
104//! ldap3::drive!(conn);
105//! let (rs, _res) = ldap.search(
106//! "ou=Places,dc=example,dc=org",
107//! Scope::Subtree,
108//! "(&(objectClass=locality)(l=ma*))",
109//! vec!["l"]
110//! ).await?.success()?;
111//! for entry in rs {
112//! println!("{:?}", SearchEntry::construct(entry));
113//! }
114//! Ok(ldap.unbind().await?)
115//! }
116//! ```
117
118#![cfg_attr(docsrs, feature(doc_cfg))]
119
120#[doc(hidden)]
121#[macro_use]
122pub extern crate log;
123#[doc(hidden)]
124pub use tokio;
125
126/// Type alias for the LDAP message ID.
127pub type RequestId = i32;
128
129pub mod adapters;
130pub mod asn1 {
131 //! ASN.1 structure construction and parsing.
132 //!
133 //! This section is deliberately under-documented; it's expected that the ASN.1 subsystem will
134 //! be extensively overhauled in the future. If you need examples of using the present interface
135 //! for, e.g., implementing a new extended operation or a control, consult the source of existing
136 //! exops/controls.
137 pub use lber::IResult;
138 pub use lber::common::TagClass;
139 pub use lber::parse::{parse_tag, parse_uint};
140 pub use lber::structure::{PL, StructureTag};
141 pub use lber::structures::{
142 ASNTag, Boolean, Enumerated, ExplicitTag, Integer, Null, OctetString, Sequence, Set, Tag,
143 };
144 pub use lber::universal::Types;
145 pub use lber::write;
146}
147mod conn;
148pub mod controls {
149 //! Control construction and parsing.
150 //!
151 //! A control can be associated with a request or a response. Several common
152 //! controls, such as [`PagedResults`](struct.PagedResults.html), are implemented
153 //! directly by this library. If an implemented control has the same form for
154 //! the request and the response, there will be a single structure for both.
155 //! (This is the case for `PagedResults`.) If the response control is different,
156 //! its name will consist of the request control name with the `Resp` suffix.
157 //!
158 //! A request control can be created by instantiating its structure and converting
159 //! it to ASN.1 with `into()` when passing the instance or constructing the request
160 //! control vector in the call to [`with_controls()`](../struct.LdapConn.html#method.with_controls).
161 //! A third-party control must implement the conversion from an instance
162 //! of itself to [`RawControl`](struct.RawControl.html), a general form of control.
163 //!
164 //! `RawControl`, together with an optional instance of [`ControlType`](enum.ControlType.html),
165 //! forms the type [`Control`](struct.Control.html); a vector of `Control`s is part
166 //! of the result of all LDAP operation which return one.
167 //!
168 //! The first element of `Control` will have a value if the parser recognizes
169 //! the control's OID as one that is implemented by the library itself. Since the
170 //! list of implemented controls is expected to grow, the `ControlType` enum cannot
171 //! be exhaustively matched.
172 //!
173 //! A recognized response control can be parsed by calling
174 //! [`parse()`](struct.RawControl.html#method.parse) on the instance of `RawControl`
175 //! representing it. A third-party control must implement the
176 //! [`ControlParser`](trait.ControlParser.html) trait to support this interface.
177 //!
178 //! ### Example
179 //!
180 //! With an `LdapResult` in `res`, iterating through controls and matching the desired ones
181 //! could be done like this:
182 //!
183 //! ```rust,no_run
184 //! # use ldap3::controls::{Control, ControlType, PagedResults};
185 //! # use ldap3::result::Result;
186 //! # use ldap3::LdapConn;
187 //! # fn main() -> Result<()> {
188 //! # let mut ldap = LdapConn::new("ldap://localhost")?;
189 //! # let res = ldap.simple_bind("", "")?.success()?;
190 //! for ctrl in res.ctrls {
191 //! match ctrl {
192 //! // matching a control implemented by the library
193 //! Control(Some(ControlType::PagedResults), ref raw) => {
194 //! dbg!(raw.parse::<PagedResults>());
195 //! },
196 //! // matching a control unknown to the library
197 //! // the OID is actually that of PagedResults
198 //! Control(None, ref raw) if raw.ctype == "1.2.840.113556.1.4.319" => {
199 //! dbg!(raw.parse::<PagedResults>());
200 //! },
201 //! _ => (),
202 //! }
203 //! }
204 //! # Ok(())
205 //! # }
206 pub use crate::controls_impl::TxnSpec;
207 pub use crate::controls_impl::parse_syncinfo;
208 pub use crate::controls_impl::{
209 Assertion, ManageDsaIt, MatchedValues, PagedResults, ProxyAuth, RelaxRules,
210 };
211 pub use crate::controls_impl::{
212 Control, ControlParser, ControlType, CriticalControl, IntoRawControlVec, MakeCritical,
213 RawControl,
214 };
215 pub use crate::controls_impl::{
216 EntryState, RefreshMode, SyncDone, SyncInfo, SyncRequest, SyncState,
217 };
218 pub use crate::controls_impl::{PostRead, PostReadResp, PreRead, PreReadResp, ReadEntryResp};
219}
220mod controls_impl;
221mod exop_impl;
222pub mod exop {
223 //! Extended operation construction and parsing.
224 //!
225 //! A generic exop is represented by [`Exop`](struct.Exop.html). If a particular
226 //! exop is implemented by this library, it may have one or two associated structs;
227 //! one for constructing requests, and another for parsing responses. If request and
228 //! response are the same, there is only the request struct; if they are different,
229 //! the response struct's name will consist of the request struct name with the
230 //! `Resp` suffix.
231 //!
232 //! A request struct must implement the `From` conversion of itself into `Exop`.
233 //! A response struct must implement the [`ExopParser`](trait.ExopParser.html)
234 //! trait.
235 pub use crate::exop_impl::{
236 EndTxn, EndTxnResp, Exop, ExopParser, PasswordModify, PasswordModifyResp, StartTxn,
237 StartTxnResp, WhoAmI, WhoAmIResp,
238 };
239}
240mod filter;
241mod ldap;
242mod protocol;
243pub mod result;
244mod search;
245#[cfg(feature = "sync")]
246mod sync;
247mod util;
248
249pub use conn::{LdapConnAsync, LdapConnSettings, StdStream};
250pub use filter::parse as parse_filter;
251pub use ldap::{Ldap, Mod};
252pub use result::{LdapError, LdapResult, SearchResult};
253pub use search::parse_refs;
254pub use search::{
255 DerefAliases, ResultEntry, Scope, SearchEntry, SearchOptions, SearchStream, StreamState,
256};
257#[cfg(feature = "sync")]
258pub use sync::{EntryStream, LdapConn};
259pub use util::{LdapUrlExt, LdapUrlParams, dn_escape, get_url_params, ldap_escape, ldap_unescape};