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};