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.11.5"
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//! * __tls__ (enabled by default): TLS support, backed by the `native-tls` crate, which uses
44//! a platform-specific TLS backend. This is an alias for __tls-native__.
45//!
46//! * __tls-rustls__ (disabled by default): TLS support, backed by the Rustls library.
47//!
48//! Without any features, only plain TCP connections (and Unix domain sockets on Unix-like
49//! platforms) are available. For TLS support, __tls__ and __tls-rustls__ are mutually
50//! exclusive: choosing both will produce a compile-time error.
51//!
52//! ## Examples
53//!
54//! The following two examples perform exactly the same operation and should produce identical
55//! results. They should be run against the example server in the `data` subdirectory of the crate source.
56//! Other sample programs expecting the same server setup can be found in the `examples` subdirectory.
57//!
58//! ### Synchronous search
59//!
60//! ```rust,no_run
61//! use ldap3::{LdapConn, Scope, SearchEntry};
62//! use ldap3::result::Result;
63//!
64//! fn main() -> Result<()> {
65//! let mut ldap = LdapConn::new("ldap://localhost:2389")?;
66//! let (rs, _res) = ldap.search(
67//! "ou=Places,dc=example,dc=org",
68//! Scope::Subtree,
69//! "(&(objectClass=locality)(l=ma*))",
70//! vec!["l"]
71//! )?.success()?;
72//! for entry in rs {
73//! println!("{:?}", SearchEntry::construct(entry));
74//! }
75//! Ok(ldap.unbind()?)
76//! }
77//! ```
78//!
79//! ### Asynchronous search
80//!
81//! ```rust,no_run
82//! use ldap3::{LdapConnAsync, Scope, SearchEntry};
83//! use ldap3::result::Result;
84//!
85//! #[tokio::main]
86//! async fn main() -> Result<()> {
87//! let (conn, mut ldap) = LdapConnAsync::new("ldap://localhost:2389").await?;
88//! ldap3::drive!(conn);
89//! let (rs, _res) = ldap.search(
90//! "ou=Places,dc=example,dc=org",
91//! Scope::Subtree,
92//! "(&(objectClass=locality)(l=ma*))",
93//! vec!["l"]
94//! ).await?.success()?;
95//! for entry in rs {
96//! println!("{:?}", SearchEntry::construct(entry));
97//! }
98//! Ok(ldap.unbind().await?)
99//! }
100//! ```
101
102#![cfg_attr(docsrs, feature(doc_cfg))]
103
104#[doc(hidden)]
105#[macro_use]
106pub extern crate log;
107#[doc(hidden)]
108pub use tokio;
109
110/// Type alias for the LDAP message ID.
111pub type RequestId = i32;
112
113pub mod adapters;
114pub mod asn1 {
115 //! ASN.1 structure construction and parsing.
116 //!
117 //! This section is deliberately under-documented; it's expected that the ASN.1 subsystem will
118 //! be extensively overhauled in the future. If you need examples of using the present interface
119 //! for, e.g., implementing a new extended operation or a control, consult the source of existing
120 //! exops/controls.
121 pub use lber::common::TagClass;
122 pub use lber::parse::{parse_tag, parse_uint};
123 pub use lber::structure::{StructureTag, PL};
124 pub use lber::structures::{
125 ASNTag, Boolean, Enumerated, ExplicitTag, Integer, Null, OctetString, Sequence, Set, Tag,
126 };
127 pub use lber::universal::Types;
128 pub use lber::write;
129 pub use lber::IResult;
130}
131mod conn;
132pub mod controls {
133 //! Control construction and parsing.
134 //!
135 //! A control can be associated with a request or a response. Several common
136 //! controls, such as [`PagedResults`](struct.PagedResults.html), are implemented
137 //! directly by this library. If an implemented control has the same form for
138 //! the request and the response, there will be a single structure for both.
139 //! (This is the case for `PagedResults`.) If the response control is different,
140 //! its name will consist of the request control name with the `Resp` suffix.
141 //!
142 //! A request control can be created by instantiating its structure and converting
143 //! it to ASN.1 with `into()` when passing the instance or constructing the request
144 //! control vector in the call to [`with_controls()`](../struct.LdapConn.html#method.with_controls).
145 //! A third-party control must implement the conversion from an instance
146 //! of itself to [`RawControl`](struct.RawControl.html), a general form of control.
147 //!
148 //! `RawControl`, together with an optional instance of [`ControlType`](enum.ControlType.html),
149 //! forms the type [`Control`](struct.Control.html); a vector of `Control`s is part
150 //! of the result of all LDAP operation which return one.
151 //!
152 //! The first element of `Control` will have a value if the parser recognizes
153 //! the control's OID as one that is implemented by the library itself. Since the
154 //! list of implemented controls is expected to grow, the `ControlType` enum cannot
155 //! be exhaustively matched.
156 //!
157 //! A recognized response control can be parsed by calling
158 //! [`parse()`](struct.RawControl.html#method.parse) on the instance of `RawControl`
159 //! representing it. A third-party control must implement the
160 //! [`ControlParser`](trait.ControlParser.html) trait to support this interface.
161 //!
162 //! ### Example
163 //!
164 //! With an `LdapResult` in `res`, iterating through controls and matching the desired ones
165 //! could be done like this:
166 //!
167 //! ```rust,no_run
168 //! # use ldap3::controls::{Control, ControlType, PagedResults};
169 //! # use ldap3::result::Result;
170 //! # use ldap3::LdapConn;
171 //! # fn main() -> Result<()> {
172 //! # let mut ldap = LdapConn::new("ldap://localhost")?;
173 //! # let res = ldap.simple_bind("", "")?.success()?;
174 //! for ctrl in res.ctrls {
175 //! match ctrl {
176 //! // matching a control implemented by the library
177 //! Control(Some(ControlType::PagedResults), ref raw) => {
178 //! dbg!(raw.parse::<PagedResults>());
179 //! },
180 //! // matching a control unknown to the library
181 //! // the OID is actually that of PagedResults
182 //! Control(None, ref raw) if raw.ctype == "1.2.840.113556.1.4.319" => {
183 //! dbg!(raw.parse::<PagedResults>());
184 //! },
185 //! _ => (),
186 //! }
187 //! }
188 //! # Ok(())
189 //! # }
190 pub use crate::controls_impl::parse_syncinfo;
191 pub use crate::controls_impl::{
192 Assertion, ManageDsaIt, MatchedValues, PagedResults, ProxyAuth, RelaxRules,
193 };
194 pub use crate::controls_impl::{
195 Control, ControlParser, ControlType, CriticalControl, IntoRawControlVec, MakeCritical,
196 RawControl,
197 };
198 pub use crate::controls_impl::{
199 EntryState, RefreshMode, SyncDone, SyncInfo, SyncRequest, SyncState,
200 };
201 pub use crate::controls_impl::{PostRead, PostReadResp, PreRead, PreReadResp, ReadEntryResp};
202}
203mod controls_impl;
204mod exop_impl;
205pub mod exop {
206 //! Extended operation construction and parsing.
207 //!
208 //! A generic exop is represented by [`Exop`](struct.Exop.html). If a particular
209 //! exop is implemented by this library, it may have one or two associated structs;
210 //! one for constructing requests, and another for parsing responses. If request and
211 //! response are the same, there is only the request struct; if they are different,
212 //! the response struct's name will consist of the request struct name with the
213 //! `Resp` suffix.
214 //!
215 //! A request struct must implement the `From` conversion of itself into `Exop`.
216 //! A response struct must implement the [`ExopParser`](trait.ExopParser.html)
217 //! trait.
218 pub use crate::exop_impl::{
219 Exop, ExopParser, PasswordModify, PasswordModifyResp, WhoAmI, WhoAmIResp,
220 };
221}
222mod filter;
223mod ldap;
224mod protocol;
225pub mod result;
226mod search;
227#[cfg(feature = "sync")]
228mod sync;
229mod util;
230
231pub use conn::{LdapConnAsync, LdapConnSettings};
232pub use filter::parse as parse_filter;
233pub use ldap::{Ldap, Mod};
234pub use result::{LdapError, LdapResult, SearchResult};
235pub use search::parse_refs;
236pub use search::{
237 DerefAliases, ResultEntry, Scope, SearchEntry, SearchOptions, SearchStream, StreamState,
238};
239#[cfg(feature = "sync")]
240pub use sync::{EntryStream, LdapConn};
241#[allow(deprecated)]
242pub use util::{
243 dn_escape, get_url_params, ldap_escape, ldap_str_unescape, ldap_unescape, LdapUrlExt,
244 LdapUrlParams,
245};