@@ -10,6 +10,7 @@ use std::ffi::{CStr, CString};
10
10
use std:: ptr;
11
11
use std:: slice;
12
12
use std:: boxed;
13
+ use std:: ptr:: null_mut;
13
14
14
15
pub mod codes;
15
16
pub mod errors;
@@ -78,6 +79,9 @@ extern "C" {
78
79
sctrls : * mut * mut LDAPControl ,
79
80
cctrls : * mut * mut LDAPControl )
80
81
-> c_int ;
82
+ fn ldap_start_tls_s ( ldap : * mut LDAP ,
83
+ scrtrls : * mut * mut LDAPControl ,
84
+ cctrls : * mut * mut LDAPControl ) -> c_int ;
81
85
}
82
86
83
87
/// A typedef for an `LDAPResponse` type.
@@ -270,6 +274,55 @@ impl RustLDAP {
270
274
-1 )
271
275
}
272
276
277
+ /// Installs TLS handlers on the session
278
+ ///
279
+ /// # Examples
280
+ ///
281
+ /// ```
282
+ /// use openldap::RustLDAP;
283
+ /// let ldap = RustLDAP::new(&"ldaps://myserver:636");
284
+ ///
285
+ /// ldap.set_option(
286
+ /// openldap::codes::options::LDAP_OPT_PROTOCOL_VERSION,
287
+ /// &openldap::codes::versions::LDAP_VERSION3,
288
+ /// );
289
+ ///
290
+ /// ldap.set_option(
291
+ /// openldap::codes::options::LDAP_OPT_X_TLS_REQUIRE_CERT,
292
+ /// &openldap::codes::options::LDAP_OPT_X_TLS_ALLOW,
293
+ /// );
294
+ ///
295
+ /// ldap.set_option(openldap::codes::options::LDAP_OPT_X_TLS_NEWCTX, &0);
296
+ ///
297
+ /// ldap.start_tls(None, None);
298
+ /// ldap.simple_bind("some-dn", "some-password").unwrap()
299
+ /// ```
300
+ pub fn start_tls ( & self , serverctrls : Option < * mut * mut LDAPControl > , clientctrls : Option < * mut * mut LDAPControl > ) -> Result < i32 , errors:: LDAPError > {
301
+ let r_serverctrls = match serverctrls {
302
+ Some ( sc) => sc,
303
+ None => ptr:: null_mut ( ) ,
304
+ } ;
305
+
306
+ let r_clientctrls = match clientctrls {
307
+ Some ( cc) => cc,
308
+ None => ptr:: null_mut ( ) ,
309
+ } ;
310
+
311
+ unsafe {
312
+ let res = ldap_start_tls_s ( self . ldap_ptr , r_serverctrls, r_clientctrls) ;
313
+
314
+ if res < 0 {
315
+ let raw_estr = ldap_err2string ( res as c_int ) ;
316
+ return Err ( errors:: LDAPError :: NativeError ( CStr :: from_ptr ( raw_estr)
317
+ . to_owned ( )
318
+ . into_string ( )
319
+ . unwrap ( ) ) ) ;
320
+ }
321
+
322
+ Ok ( res)
323
+ }
324
+ }
325
+
273
326
/// Advanced synchronous search.
274
327
///
275
328
/// Exposes a raw API around the underlying `ldap_search_ext_s` function from `OpenLDAP`.
@@ -483,6 +536,32 @@ mod tests {
483
536
484
537
}
485
538
539
+ #[ test]
540
+ fn test_simple_bind_with_start_tls ( ) {
541
+ let ldap = super :: RustLDAP :: new ( TEST_ADDRESS ) . unwrap ( ) ;
542
+
543
+ assert ! ( ldap. set_option( codes:: options:: LDAP_OPT_PROTOCOL_VERSION , & 3 ) ) ;
544
+ ldap. start_tls ( None , None ) ;
545
+
546
+ ldap. set_option (
547
+ codes:: options:: LDAP_OPT_PROTOCOL_VERSION ,
548
+ & codes:: versions:: LDAP_VERSION3 ,
549
+ ) ;
550
+
551
+ ldap. set_option (
552
+ codes:: options:: LDAP_OPT_X_TLS_REQUIRE_CERT ,
553
+ & codes:: options:: LDAP_OPT_X_TLS_ALLOW ,
554
+ ) ;
555
+
556
+ ldap. set_option ( codes:: options:: LDAP_OPT_X_TLS_NEWCTX , & 0 ) ;
557
+
558
+ let res = ldap. simple_bind ( TEST_BIND_DN , TEST_BIND_PASS ) . unwrap ( ) ;
559
+ assert_eq ! ( codes:: results:: LDAP_SUCCESS , res) ;
560
+ println ! ( "Bind result: {:?}" , res) ;
561
+
562
+ }
563
+
564
+
486
565
#[ test]
487
566
fn test_simple_search ( ) {
488
567
0 commit comments